From b7a0325965be7cd227d9d9d0657581a7f6a59434 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Feb 2023 18:01:01 -0800 Subject: [PATCH 01/54] sage.features: Add 'sage.libs.singular' --- src/sage/features/singular.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index 610e195c641..9c6a0942fa0 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -25,3 +25,35 @@ def __init__(self): """ Executable.__init__(self, "singular", SINGULAR_BIN, spkg='singular') + + +class sage__libs__singular(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.singular` + (the library interface to Singular) and :mod:`sage.interfaces.singular` (the pexpect + interface to Singular). By design, we do not distinguish between these two, in order + to facilitate the conversion of code from the pexpect interface to the library + interface. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__singular + sage: sage__libs__singular().is_present() # optional - sage.libs.singular + FeatureTestResult('sage.libs.singular', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.singular import sage__libs__singular + sage: isinstance(sage__libs__singular(), sage__libs__singular) + True + """ + JoinFeature.__init__(self, 'sage.libs.singular', + [PythonModule('sage.libs.singular.singular'), + PythonModule('sage.interfaces.singular')]) + + +def all_features(): + return [Singular(), + sage__libs__singular()] From 6557578596af0c4dfa821702442d48b6817c8b9b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Feb 2023 21:15:31 -0800 Subject: [PATCH 02/54] sage.features: Add 'sage.libs.singular' (fixup) --- src/sage/features/singular.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index 9c6a0942fa0..9c9f2f65be9 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -1,7 +1,8 @@ r""" Features for testing the presence of Singular """ -from . import Executable +from . import Executable, PythonModule +from .join_feature import JoinFeature from sage.env import SINGULAR_BIN From 8f05e2c85f24d0cb95cce2e5f9d5221df9a8da10 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Feb 2023 00:41:21 -0800 Subject: [PATCH 03/54] src/sage/features/singular.py: Fix up doctest --- src/sage/features/singular.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index 9c9f2f65be9..d02ef78a06b 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -38,7 +38,7 @@ class sage__libs__singular(JoinFeature): EXAMPLES:: - sage: from sage.features.sagemath import sage__libs__singular + sage: from sage.features.singular import sage__libs__singular sage: sage__libs__singular().is_present() # optional - sage.libs.singular FeatureTestResult('sage.libs.singular', True) """ From ebac0f203dd0921d296ff7bbe475df81153d26f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 15:21:02 -0800 Subject: [PATCH 04/54] sage.features.standard: New --- src/sage/features/standard.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/sage/features/standard.py diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py new file mode 100644 index 00000000000..54340c51dff --- /dev/null +++ b/src/sage/features/standard.py @@ -0,0 +1,26 @@ +r""" +Check for various standard packages (for modularized distributions) + +These features are provided by standard packages in the Sage distribution. +""" +from . import PythonModule +from . import JoinFeature + + +def all_features(): + return [PythonModule('cvxopt', spkg='cvxopt'), + PythonModule('fpylll', spkg='fpylll'), + PythonModule('IPython', spkg='ipython'), + PythonModule('lrcalc', spkg='lrcalc_python'), + PythonModule('mpmath', spkg='mpmath'), + PythonModule('networkx', spkg='networkx'), + PythonModule('numpy', spkg='numpy'), + PythonModule('pexpect', spkg='pexpect'), + PythonModule('PIL', spkg='pillow'), + PythonModule('ppl', spkg='pplpy'), + PythonModule('primecountpy', spkg='primecountpy'), + PythonModule('ptyprocess', spkg='ptyprocess'), + PythonModule('requests', spkg='requests'), + PythonModule('rpy2', spkg='rpy2'), + PythonModule('scipy', spkg='scipy'), + PythonModule('sympy', spkg='sympy')] From a9fc02ed3f3af963d18100a610cf484cb34ff44b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 21:44:26 -0800 Subject: [PATCH 05/54] src/sage/features/standard.py: Fix up, rename features to match spkgs --- src/sage/features/standard.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index 54340c51dff..307c973a390 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -4,20 +4,20 @@ These features are provided by standard packages in the Sage distribution. """ from . import PythonModule -from . import JoinFeature +from .join_feature import JoinFeature def all_features(): return [PythonModule('cvxopt', spkg='cvxopt'), PythonModule('fpylll', spkg='fpylll'), - PythonModule('IPython', spkg='ipython'), - PythonModule('lrcalc', spkg='lrcalc_python'), + JoinFeature('ipython', [PythonModule('IPython')], spkg='ipython'), + JoinFeature('lrcalc_python', [PythonModule('lrcalc')], spkg='lrcalc_python'), PythonModule('mpmath', spkg='mpmath'), PythonModule('networkx', spkg='networkx'), PythonModule('numpy', spkg='numpy'), PythonModule('pexpect', spkg='pexpect'), - PythonModule('PIL', spkg='pillow'), - PythonModule('ppl', spkg='pplpy'), + JoinFeature('pillow', [PythonModule('PIL')], spkg='pillow'), + JoinFeature('pplpy', [PythonModule('ppl')], spkg='pplpy'), PythonModule('primecountpy', spkg='primecountpy'), PythonModule('ptyprocess', spkg='ptyprocess'), PythonModule('requests', spkg='requests'), From 2fafd825073de8caf3153e457891013b54c931d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 23:33:58 -0800 Subject: [PATCH 06/54] src/sage/features/standard.py: Fix up --- src/sage/features/standard.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index 307c973a390..f2976bdea37 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -10,14 +10,14 @@ def all_features(): return [PythonModule('cvxopt', spkg='cvxopt'), PythonModule('fpylll', spkg='fpylll'), - JoinFeature('ipython', [PythonModule('IPython')], spkg='ipython'), - JoinFeature('lrcalc_python', [PythonModule('lrcalc')], spkg='lrcalc_python'), + JoinFeature('ipython', (PythonModule('IPython'),), spkg='ipython'), + JoinFeature('lrcalc_python', (PythonModule('lrcalc'),), spkg='lrcalc_python'), PythonModule('mpmath', spkg='mpmath'), PythonModule('networkx', spkg='networkx'), PythonModule('numpy', spkg='numpy'), PythonModule('pexpect', spkg='pexpect'), - JoinFeature('pillow', [PythonModule('PIL')], spkg='pillow'), - JoinFeature('pplpy', [PythonModule('ppl')], spkg='pplpy'), + JoinFeature('pillow', (PythonModule('PIL'),), spkg='pillow'), + JoinFeature('pplpy', (PythonModule('ppl'),), spkg='pplpy'), PythonModule('primecountpy', spkg='primecountpy'), PythonModule('ptyprocess', spkg='ptyprocess'), PythonModule('requests', spkg='requests'), From 86a2c579da0b4419f39a06ebe03ce44d58f4f644 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 7 Mar 2023 12:55:22 -0800 Subject: [PATCH 07/54] src/sage/features: Add/update copyright according to "git blame -w --date=format:%Y FILE | sort -k2" --- src/sage/features/__init__.py | 13 +++++++++++++ src/sage/features/all.py | 9 +++++++++ src/sage/features/bliss.py | 13 ++++++++++++- src/sage/features/cddlib.py | 10 ++++++++++ src/sage/features/csdp.py | 12 ++++++++++++ src/sage/features/cython.py | 10 +++++++++- src/sage/features/databases.py | 15 ++++++++++++++- src/sage/features/dvipng.py | 1 - src/sage/features/ffmpeg.py | 3 +-- src/sage/features/gap.py | 10 +++++++++- src/sage/features/gfan.py | 9 +++++++++ src/sage/features/graph_generators.py | 14 +++++++++++++- src/sage/features/graphviz.py | 4 +++- src/sage/features/igraph.py | 11 +++++++++++ src/sage/features/imagemagick.py | 4 ++-- src/sage/features/interfaces.py | 11 +++++++++++ src/sage/features/internet.py | 10 ++++++++++ src/sage/features/join_feature.py | 11 +++++++++++ src/sage/features/kenzo.py | 14 +++++++++++++- src/sage/features/latex.py | 5 ++++- src/sage/features/latte.py | 15 ++++++++++++++- src/sage/features/lrs.py | 13 +++++++++++++ src/sage/features/mcqd.py | 9 +++++++++ src/sage/features/meataxe.py | 11 +++++++++++ src/sage/features/mip_backends.py | 10 ++++++++++ src/sage/features/msolve.py | 9 +++++++++ src/sage/features/nauty.py | 9 +++++++++ src/sage/features/normaliz.py | 10 ++++++++++ src/sage/features/pandoc.py | 1 + src/sage/features/pdf2svg.py | 1 - src/sage/features/phitigra.py | 10 ++++++++++ src/sage/features/pkg_systems.py | 10 ++++++++++ src/sage/features/polymake.py | 10 ++++++++++ src/sage/features/poppler.py | 1 - src/sage/features/rubiks.py | 5 ++++- src/sage/features/sagemath.py | 11 +++++++++++ src/sage/features/singular.py | 10 ++++++++++ src/sage/features/sphinx.py | 10 ++++++++++ src/sage/features/standard.py | 10 ++++++++++ src/sage/features/tdlib.py | 10 ++++++++++ 40 files changed, 347 insertions(+), 17 deletions(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index cb2e2a085c3..fc60ac746b7 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -52,6 +52,19 @@ As can be seen above, features try to produce helpful error messages. """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# 2018 Timo Kaufmann +# 2019-2022 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from __future__ import annotations import os diff --git a/src/sage/features/all.py b/src/sage/features/all.py index 2ec0c267b83..19eabe60126 100644 --- a/src/sage/features/all.py +++ b/src/sage/features/all.py @@ -2,6 +2,15 @@ Enumeration of all defined features """ +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + def all_features(): r""" Return an iterable of all features. diff --git a/src/sage/features/bliss.py b/src/sage/features/bliss.py index e8efd3e8f97..aeadedfebff 100644 --- a/src/sage/features/bliss.py +++ b/src/sage/features/bliss.py @@ -1,7 +1,18 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``bliss`` """ + +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import CythonFeature, PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/cddlib.py b/src/sage/features/cddlib.py index 59a72a2120f..5badbd251c0 100644 --- a/src/sage/features/cddlib.py +++ b/src/sage/features/cddlib.py @@ -1,6 +1,16 @@ r""" Feature for testing the presence of ``cddlib`` """ + +# ***************************************************************************** +# Copyright (C) 2022 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import Executable diff --git a/src/sage/features/csdp.py b/src/sage/features/csdp.py index e86ec415d09..9c04779558c 100644 --- a/src/sage/features/csdp.py +++ b/src/sage/features/csdp.py @@ -3,6 +3,18 @@ Feature for testing the presence of ``csdp`` """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# 2019 David Coudert +# 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + import os import re import subprocess diff --git a/src/sage/features/cython.py b/src/sage/features/cython.py index f537843f4f4..8f03155ac2f 100644 --- a/src/sage/features/cython.py +++ b/src/sage/features/cython.py @@ -1,8 +1,16 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``cython`` """ +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import CythonFeature diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index d1e77a8ff32..7fa05ca099a 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -1,8 +1,21 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of various databases """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018-2019 Jeroen Demeyer +# 2018 Timo Kaufmann +# 2020-2022 Matthias Koeppe +# 2020-2022 Sebastian Oehms +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import StaticFile, PythonModule from sage.env import ( diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py index 44ef6c7074a..281084a6e72 100644 --- a/src/sage/features/dvipng.py +++ b/src/sage/features/dvipng.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Feature for testing the presence of ``dvipng`` """ diff --git a/src/sage/features/ffmpeg.py b/src/sage/features/ffmpeg.py index bb708478251..681af26494c 100644 --- a/src/sage/features/ffmpeg.py +++ b/src/sage/features/ffmpeg.py @@ -1,9 +1,8 @@ -# -*- coding: utf-8 -*- r""" Feature for testing the presence of ``ffmpeg`` """ # **************************************************************************** -# Copyright (C) 2018 Sebastien Labbe +# Copyright (C) 2018-2022 Sebastien Labbe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/sage/features/gap.py b/src/sage/features/gap.py index 20add30c114..b382b8a7184 100644 --- a/src/sage/features/gap.py +++ b/src/sage/features/gap.py @@ -1,7 +1,15 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of GAP packages """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** from . import Feature, FeatureTestResult diff --git a/src/sage/features/gfan.py b/src/sage/features/gfan.py index 6551ca5340c..d9a74db9e1b 100644 --- a/src/sage/features/gfan.py +++ b/src/sage/features/gfan.py @@ -2,6 +2,15 @@ Features for testing the presence of ``gfan`` """ +# ***************************************************************************** +# Copyright (C) 2022 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import Executable diff --git a/src/sage/features/graph_generators.py b/src/sage/features/graph_generators.py index 0ecd63bad76..3d484c59f6b 100644 --- a/src/sage/features/graph_generators.py +++ b/src/sage/features/graph_generators.py @@ -1,8 +1,20 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of various graph generator programs """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# 2019 Frédéric Chapoton +# 2021 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + import os import subprocess diff --git a/src/sage/features/graphviz.py b/src/sage/features/graphviz.py index 0a0c8ba88e9..2105eda9d8c 100644 --- a/src/sage/features/graphviz.py +++ b/src/sage/features/graphviz.py @@ -1,9 +1,10 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``graphviz`` """ + # **************************************************************************** # Copyright (C) 2018 Sebastien Labbe +# 2021 Matthias Koeppe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -11,6 +12,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + from . import Executable from .join_feature import JoinFeature diff --git a/src/sage/features/igraph.py b/src/sage/features/igraph.py index 04ac4efbb54..6bb83294a95 100644 --- a/src/sage/features/igraph.py +++ b/src/sage/features/igraph.py @@ -1,6 +1,17 @@ r""" Check for igraph """ + +# **************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index 59e35cb5a7a..b7aa3aeb9a2 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Feature for testing the presence of ``imagemagick`` @@ -7,8 +6,9 @@ ``identify``, ``composite``, ``montage``, ``compare``, etc. could be also checked in this module. """ + # **************************************************************************** -# Copyright (C) 2018 Sebastien Labbe +# Copyright (C) 2018-2022 Sebastien Labbe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/sage/features/interfaces.py b/src/sage/features/interfaces.py index b77c2cc4f88..e31e7b72d61 100644 --- a/src/sage/features/interfaces.py +++ b/src/sage/features/interfaces.py @@ -1,6 +1,17 @@ r""" Features for testing whether interpreter interfaces are functional """ + +# **************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + import importlib from . import Feature, FeatureTestResult, PythonModule diff --git a/src/sage/features/internet.py b/src/sage/features/internet.py index 6e800120828..f1eb000fe92 100644 --- a/src/sage/features/internet.py +++ b/src/sage/features/internet.py @@ -2,6 +2,16 @@ Feature for testing if the Internet is available """ +# **************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from . import Feature, FeatureTestResult diff --git a/src/sage/features/join_feature.py b/src/sage/features/join_feature.py index 94830eead1e..d02ad669833 100644 --- a/src/sage/features/join_feature.py +++ b/src/sage/features/join_feature.py @@ -2,6 +2,17 @@ Join features """ +# **************************************************************************** +# Copyright (C) 2021-2022 Matthias Koeppe +# 2021-2022 Kwankyu Lee +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from . import Feature, FeatureTestResult diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index df2e658e975..655602427b8 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -1,8 +1,20 @@ -# -*- coding: utf-8 -*- r""" Feature for testing the presence of ``kenzo`` """ +# **************************************************************************** +# Copyright (C) 2020 Travis Scrimshaw +# 2021 Matthias Koeppe +# 2021 Michael Orlitzky +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + + from . import Feature, FeatureTestResult class Kenzo(Feature): diff --git a/src/sage/features/latex.py b/src/sage/features/latex.py index 02bcb57a0ca..1b01db39f67 100644 --- a/src/sage/features/latex.py +++ b/src/sage/features/latex.py @@ -1,9 +1,12 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``latex`` and equivalent programs """ + # **************************************************************************** # Copyright (C) 2021 Sebastien Labbe +# 2021 Matthias Koeppe +# 2022 Kwankyu Lee +# 2022 Sebastian Oehms # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/sage/features/latte.py b/src/sage/features/latte.py index 6202152501f..e88752bd561 100644 --- a/src/sage/features/latte.py +++ b/src/sage/features/latte.py @@ -1,7 +1,20 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``latte_int`` """ + +# **************************************************************************** +# Copyright (C) 2018 Vincent Delecroix +# 2019 Frédéric Chapoton +# 2021 Matthias Koeppe +# 2021 Kwankyu Lee +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from . import Executable from .join_feature import JoinFeature diff --git a/src/sage/features/lrs.py b/src/sage/features/lrs.py index d7b15fbcdd6..501d1d371e7 100644 --- a/src/sage/features/lrs.py +++ b/src/sage/features/lrs.py @@ -3,6 +3,19 @@ Feature for testing the presence of ``lrslib`` """ +# ***************************************************************************** +# Copyright (C) 2016 Julian Rüth +# 2018 Jeroen Demeyer +# 2021-2022 Matthias Koeppe +# 2021 Kwankyu Lee +# 2022 Sébastien Labbé +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + import subprocess from . import Executable, FeatureTestResult diff --git a/src/sage/features/mcqd.py b/src/sage/features/mcqd.py index 131b175aabc..faf7ace441d 100644 --- a/src/sage/features/mcqd.py +++ b/src/sage/features/mcqd.py @@ -2,6 +2,15 @@ Features for testing the presence of ``mcqd`` """ +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/meataxe.py b/src/sage/features/meataxe.py index d3f7fce200e..78de1bdfe03 100644 --- a/src/sage/features/meataxe.py +++ b/src/sage/features/meataxe.py @@ -2,6 +2,17 @@ Feature for testing the presence of ``meataxe`` """ +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/mip_backends.py b/src/sage/features/mip_backends.py index 477d88efabf..d276e25abe8 100644 --- a/src/sage/features/mip_backends.py +++ b/src/sage/features/mip_backends.py @@ -2,6 +2,16 @@ Features for testing the presence of :class:`MixedIntegerLinearProgram` backends """ +# ***************************************************************************** +# Copyright (C) 2021-2022 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import Feature, PythonModule, FeatureTestResult from .join_feature import JoinFeature diff --git a/src/sage/features/msolve.py b/src/sage/features/msolve.py index a7c7d5441b7..557632ff500 100644 --- a/src/sage/features/msolve.py +++ b/src/sage/features/msolve.py @@ -9,6 +9,15 @@ - :mod:`sage.rings.polynomial.msolve` """ +# ***************************************************************************** +# Copyright (C) 2022 Marc Mezzarobba +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + import subprocess from . import Executable from . import FeatureTestResult diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index 86683eb29df..f3df59f4a9c 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -2,6 +2,15 @@ Features for testing the presence of nauty executables """ +# ***************************************************************************** +# Copyright (C) 2022 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from sage.env import SAGE_NAUTY_BINS_PREFIX from . import Executable diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py index 5c3ab4255f3..acf8c9242c1 100644 --- a/src/sage/features/normaliz.py +++ b/src/sage/features/normaliz.py @@ -1,6 +1,16 @@ r""" Feature for testing the presence of ``pynormaliz`` """ + +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/pandoc.py b/src/sage/features/pandoc.py index 0a2bbcdacdb..a00a2b6f8e4 100644 --- a/src/sage/features/pandoc.py +++ b/src/sage/features/pandoc.py @@ -4,6 +4,7 @@ """ # **************************************************************************** # Copyright (C) 2018 Thierry Monteil +# 2021 Matthias Koeppe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py index 9de3fb3cfd6..2b60574fe85 100644 --- a/src/sage/features/pdf2svg.py +++ b/src/sage/features/pdf2svg.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Feature for testing the presence of ``pdf2svg`` """ diff --git a/src/sage/features/phitigra.py b/src/sage/features/phitigra.py index f792d7b47cd..60ef8f46dde 100644 --- a/src/sage/features/phitigra.py +++ b/src/sage/features/phitigra.py @@ -1,6 +1,16 @@ r""" Check for phitigra """ + +# ***************************************************************************** +# Copyright (C) 2022 Jean-Florent Raymond +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule diff --git a/src/sage/features/pkg_systems.py b/src/sage/features/pkg_systems.py index 5e31ec9f66d..334f8378050 100644 --- a/src/sage/features/pkg_systems.py +++ b/src/sage/features/pkg_systems.py @@ -1,6 +1,16 @@ r""" Features for testing the presence of package systems """ + +# ***************************************************************************** +# Copyright (C) 2021-2022 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import Feature diff --git a/src/sage/features/polymake.py b/src/sage/features/polymake.py index 579951c047f..6168c6c9978 100644 --- a/src/sage/features/polymake.py +++ b/src/sage/features/polymake.py @@ -1,6 +1,16 @@ r""" Feature for testing the presence of the Python interface to polymake """ + +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/poppler.py b/src/sage/features/poppler.py index 1b0379bc0d2..b8f8586e7f5 100644 --- a/src/sage/features/poppler.py +++ b/src/sage/features/poppler.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Check for poppler features diff --git a/src/sage/features/rubiks.py b/src/sage/features/rubiks.py index b418c1571cb..b9bd2f126f7 100644 --- a/src/sage/features/rubiks.py +++ b/src/sage/features/rubiks.py @@ -1,14 +1,17 @@ -# -*- coding: utf-8 -*- r""" Features for testing the presence of ``rubiks`` """ # **************************************************************************** +# Copyright (C) 2020 John H. Palmieri +# 2021-2022 Matthias Koeppe +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + from sage.env import RUBIKS_BINS_PREFIX from . import Executable diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 58552614425..c8824682d60 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -1,6 +1,17 @@ r""" Features for testing the presence of Python modules in the Sage library """ + +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule, StaticFile from .join_feature import JoinFeature diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index d02ef78a06b..c3bd3b6be03 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -1,6 +1,16 @@ r""" Features for testing the presence of Singular """ + +# ***************************************************************************** +# Copyright (C) 2022-2023 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import Executable, PythonModule from .join_feature import JoinFeature from sage.env import SINGULAR_BIN diff --git a/src/sage/features/sphinx.py b/src/sage/features/sphinx.py index d29de3f34f4..44283765fd1 100644 --- a/src/sage/features/sphinx.py +++ b/src/sage/features/sphinx.py @@ -1,6 +1,16 @@ r""" Check for Sphinx """ + +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index f2976bdea37..99028676a20 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -3,6 +3,16 @@ These features are provided by standard packages in the Sage distribution. """ + +# ***************************************************************************** +# Copyright (C) 2023 Matthias Koeppe +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule from .join_feature import JoinFeature diff --git a/src/sage/features/tdlib.py b/src/sage/features/tdlib.py index ff38f6e23a5..afde40f7de7 100644 --- a/src/sage/features/tdlib.py +++ b/src/sage/features/tdlib.py @@ -2,6 +2,16 @@ Features for testing the presence of ``tdlib`` """ +# ***************************************************************************** +# Copyright (C) 2021 Matthias Koeppe +# 2021 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + from . import PythonModule from .join_feature import JoinFeature From 2f0583ce63cd252a958e5aec18814257801df3c7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 7 Mar 2023 17:33:12 -0800 Subject: [PATCH 08/54] sage.features: Add feature sage.libs.gap --- src/sage/features/gap.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/sage/features/gap.py b/src/sage/features/gap.py index b382b8a7184..67c905a35c3 100644 --- a/src/sage/features/gap.py +++ b/src/sage/features/gap.py @@ -11,7 +11,8 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from . import Feature, FeatureTestResult +from . import Feature, FeatureTestResult, PythonModule +from .join_feature import JoinFeature class GapPackage(Feature): @@ -56,3 +57,34 @@ def _is_present(self): else: return FeatureTestResult(self, False, reason="`{command}` evaluated to `{presence}` in GAP.".format(command=command, presence=presence)) + + +class sage__libs__gap(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.gap` + (the library interface to GAP) and :mod:`sage.interfaces.gap` (the pexpect + interface to GAP). By design, we do not distinguish between these two, in order + to facilitate the conversion of code from the pexpect interface to the library + interface. + + EXAMPLES:: + + sage: from sage.features.gap import sage__libs__gap + sage: sage__libs__gap().is_present() # optional - sage.libs.gap + FeatureTestResult('sage.libs.gap', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.gap import sage__libs__gap + sage: isinstance(sage__libs__gap(), sage__libs__gap) + True + """ + JoinFeature.__init__(self, 'sage.libs.gap', + [PythonModule('sage.libs.gap.libgap'), + PythonModule('sage.interfaces.gap')]) + + +def all_features(): + return [sage__libs__gap()] From 1c8c6bce9ffddb370cae955eb887aab03b0f2422 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Mar 2023 23:15:33 -0800 Subject: [PATCH 09/54] sage.rings.function_field: Add # optional --- src/sage/rings/function_field/constructor.py | 10 +- src/sage/rings/function_field/differential.py | 314 ++-- src/sage/rings/function_field/divisor.py | 1 + src/sage/rings/function_field/element.pyx | 224 +-- src/sage/rings/function_field/extensions.py | 80 +- .../rings/function_field/function_field.py | 835 ++++----- .../function_field_valuation.py | 182 +- src/sage/rings/function_field/ideal.py | 1494 ++++++++--------- src/sage/rings/function_field/maps.py | 458 ++--- src/sage/rings/function_field/order.py | 777 ++++----- src/sage/rings/function_field/place.py | 412 ++--- .../rings/function_field/valuation_ring.py | 1 + 12 files changed, 2400 insertions(+), 2388 deletions(-) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index a459b9e51ac..3e6966b8836 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -54,10 +54,10 @@ class FunctionFieldFactory(UniqueFactory): sage: K. = FunctionField(QQ); K Rational function field in x over Rational Field - sage: L. = FunctionField(GF(7)); L + sage: L. = FunctionField(GF(7)); L # optional - sage.libs.pari Rational function field in y over Finite Field of size 7 - sage: R. = L[] - sage: M. = L.extension(z^7-z-y); M + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^7 - z - y); M # optional - sage.libs.pari Function field in z defined by z^7 + 6*z + 6*y TESTS:: @@ -66,8 +66,8 @@ class FunctionFieldFactory(UniqueFactory): sage: L. = FunctionField(QQ) sage: K is L True - sage: M. = FunctionField(GF(7)) - sage: K is M + sage: M. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K is M # optional - sage.libs.pari False sage: N. = FunctionField(QQ) sage: K is N diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index e7d5f5a5c68..29ff02cd71a 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -8,35 +8,35 @@ The module of differentials on a function field forms an one-dimensional vector space over the function field:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: f = x + y - sage: g = 1 / y - sage: df = f.differential() - sage: dg = g.differential() - sage: dfdg = f.derivative() / g.derivative() - sage: df == dfdg * dg + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: f = x + y # optional - sage.libs.pari + sage: g = 1 / y # optional - sage.libs.pari + sage: df = f.differential() # optional - sage.libs.pari + sage: dg = g.differential() # optional - sage.libs.pari + sage: dfdg = f.derivative() / g.derivative() # optional - sage.libs.pari + sage: df == dfdg * dg # optional - sage.libs.pari True - sage: df + sage: df # optional - sage.libs.pari (x*y^2 + 1/x*y + 1) d(x) - sage: df.parent() + sage: df.parent() # optional - sage.libs.pari Space of differentials of Function field in y defined by y^3 + x^3*y + x We can compute a canonical divisor:: - sage: k = df.divisor() - sage: k.degree() + sage: k = df.divisor() # optional - sage.libs.pari + sage: k.degree() # optional - sage.libs.pari 4 - sage: k.degree() == 2 * L.genus() - 2 + sage: k.degree() == 2 * L.genus() - 2 # optional - sage.libs.pari True Exact differentials vanish and logarithmic differentials are stable under the Cartier operation:: - sage: df.cartier() + sage: df.cartier() # optional - sage.libs.pari 0 - sage: w = 1/f * df - sage: w.cartier() == w + sage: w = 1/f * df # optional - sage.libs.pari + sage: w.cartier() == w # optional - sage.libs.pari True AUTHORS: @@ -98,10 +98,10 @@ def __init__(self, parent, f, t=None): TESTS:: - sage: F. = FunctionField(GF(7)) - sage: f = x/(x^2 + x + 1) - sage: w = f.differential() - sage: TestSuite(w).run() + sage: F. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari + sage: w = f.differential() # optional - sage.libs.pari + sage: TestSuite(w).run() # optional - sage.libs.pari """ ModuleElement.__init__(self, parent) @@ -116,9 +116,9 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: y.differential() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari + sage: y.differential() # optional - sage.libs.pari (x*y^2 + 1/x*y) d(x) sage: F.=FunctionField(QQ) @@ -142,10 +142,10 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w = y.differential() - sage: latex(w) + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari + sage: w = y.differential() # optional - sage.libs.pari + sage: latex(w) # optional - sage.libs.pari \left( x y^{2} + \frac{1}{x} y \right)\, dx """ if self._f.is_zero(): # zero differential @@ -164,11 +164,11 @@ def __hash__(self): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^3 + x + x^3*Y) - sage: {x.differential(): 1} + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: {x.differential(): 1} # optional - sage.libs.pari {d(x): 1} - sage: {y.differential(): 1} + sage: {y.differential(): 1} # optional - sage.libs.pari {(x*y^2 + 1/x*y) d(x): 1} """ return hash((self.parent(), self._f)) @@ -186,16 +186,16 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w1 = y.differential() - sage: w2 = L(x).differential() - sage: w3 = (x*y).differential() - sage: w1 < w2 + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w1 = y.differential() # optional - sage.libs.pari + sage: w2 = L(x).differential() # optional - sage.libs.pari + sage: w3 = (x*y).differential() # optional - sage.libs.pari + sage: w1 < w2 # optional - sage.libs.pari False - sage: w2 < w1 + sage: w2 < w1 # optional - sage.libs.pari True - sage: w3 == x * w1 + y * w2 + sage: w3 == x * w1 + y * w2 # optional - sage.libs.pari True sage: F.=FunctionField(QQ) @@ -220,11 +220,11 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w1 = y.differential() - sage: w2 = (1/y).differential() - sage: w1 + w2 + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w1 = y.differential() # optional - sage.libs.pari + sage: w2 = (1/y).differential() # optional - sage.libs.pari + sage: w1 + w2 # optional - sage.libs.pari (((x^3 + 1)/x^2)*y^2 + 1/x*y) d(x) sage: F. = FunctionField(QQ) @@ -248,11 +248,11 @@ def _div_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w1 = y.differential() - sage: w2 = (1/y).differential() - sage: w1 / w2 + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w1 = y.differential() # optional - sage.libs.pari + sage: w2 = (1/y).differential() # optional - sage.libs.pari + sage: w1 / w2 # optional - sage.libs.pari y^2 sage: F. = FunctionField(QQ) @@ -272,11 +272,11 @@ def _neg_(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w1 = y.differential() - sage: w2 = (-y).differential() - sage: -w1 == w2 + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w1 = y.differential() # optional - sage.libs.pari + sage: w2 = (-y).differential() # optional - sage.libs.pari + sage: -w1 == w2 # optional - sage.libs.pari True sage: F. = FunctionField(QQ) @@ -299,11 +299,11 @@ def _rmul_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w1 = (1/y).differential() - sage: w2 = (-1/y^2) * y.differential() - sage: w1 == w2 + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w1 = (1/y).differential() # optional - sage.libs.pari + sage: w2 = (-1/y^2) * y.differential() # optional - sage.libs.pari + sage: w1 == w2 # optional - sage.libs.pari True sage: F.=FunctionField(QQ) @@ -328,26 +328,26 @@ def _acted_upon_(self, f, self_on_left): EXAMPLES:: - sage: K. = FunctionField(GF(31)); _. = K[] - sage: L. = K.extension(Y^2 - x); _. = L[] - sage: M. = L.extension(Z^2 - y) - sage: z.differential() + sage: K. = FunctionField(GF(31)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x); _. = L[] # optional - sage.libs.pari + sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari + sage: z.differential() # optional - sage.libs.pari (8/x*z) d(x) - sage: 1/(2*z) * y.differential() + sage: 1/(2*z) * y.differential() # optional - sage.libs.pari (8/x*z) d(x) - sage: z * x.differential() + sage: z * x.differential() # optional - sage.libs.pari (z) d(x) - sage: z * (y^2).differential() + sage: z * (y^2).differential() # optional - sage.libs.pari (z) d(x) - sage: z * (z^4).differential() + sage: z * (z^4).differential() # optional - sage.libs.pari (z) d(x) :: - sage: K.=FunctionField(GF(4)); _. = K[] - sage: L.=K.extension(Y^3 + x + x^3*Y) - sage: y * x.differential() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: y * x.differential() # optional - sage.libs.pari (y) d(x) """ F = f.parent() @@ -363,10 +363,10 @@ def divisor(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w = (1/y) * y.differential() - sage: w.divisor() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w = (1/y) * y.differential() # optional - sage.libs.pari + sage: w.divisor() # optional - sage.libs.pari - Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) - Place (x, y) @@ -394,10 +394,10 @@ def valuation(self, place): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: w = (1/y) * y.differential() - sage: [w.valuation(p) for p in L.places()] + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w = (1/y) * y.differential() # optional - sage.libs.pari + sage: [w.valuation(p) for p in L.places()] # optional - sage.libs.pari [-1, -1, -1, 0, 1, 0] """ F = self.parent().function_field() @@ -421,27 +421,27 @@ def residue(self, place): We verify the residue theorem in a rational function field:: - sage: F. = FunctionField(GF(4)) - sage: f = 0 - sage: while f == 0: + sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: f = 0 # optional - sage.libs.pari + sage: while f == 0: # optional - sage.libs.pari ....: f = F.random_element() - sage: w = 1/f * f.differential() - sage: d = f.divisor() - sage: s = d.support() - sage: sum([w.residue(p).trace() for p in s]) + sage: w = 1/f * f.differential() # optional - sage.libs.pari + sage: d = f.divisor() # optional - sage.libs.pari + sage: s = d.support() # optional - sage.libs.pari + sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari 0 and in an extension field:: - sage: K. = FunctionField(GF(7)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: f = 0 - sage: while f == 0: + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: f = 0 # optional - sage.libs.pari + sage: while f == 0: # optional - sage.libs.pari ....: f = L.random_element() - sage: w = 1/f * f.differential() - sage: d = f.divisor() - sage: s = d.support() - sage: sum([w.residue(p).trace() for p in s]) + sage: w = 1/f * f.differential() # optional - sage.libs.pari + sage: d = f.divisor() # optional - sage.libs.pari + sage: s = d.support() # optional - sage.libs.pari + sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari 0 and also in a function field of characteristic zero:: @@ -481,12 +481,12 @@ def monomial_coefficients(self, copy=True): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: d = y.differential() - sage: d + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: d = y.differential() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari ((4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)) d(x) - sage: d.monomial_coefficients() + sage: d.monomial_coefficients() # optional - sage.libs.pari {0: (4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)} """ return {0: self._f} @@ -498,16 +498,16 @@ class FunctionFieldDifferential_global(FunctionFieldDifferential): EXAMPLES:: - sage: F.=FunctionField(GF(7)) - sage: f = x/(x^2 + x + 1) - sage: f.differential() + sage: F. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari + sage: f.differential() # optional - sage.libs.pari ((6*x^2 + 1)/(x^4 + 2*x^3 + 3*x^2 + 2*x + 1)) d(x) :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: y.differential() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: y.differential() # optional - sage.libs.pari (x*y^2 + 1/x*y) d(x) """ def cartier(self): @@ -527,19 +527,19 @@ def cartier(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: f = x/y - sage: w = 1/f*f.differential() - sage: w.cartier() == w + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: f = x/y # optional - sage.libs.pari + sage: w = 1/f*f.differential() # optional - sage.libs.pari + sage: w.cartier() == w # optional - sage.libs.pari True :: - sage: F. = FunctionField(GF(4)) - sage: f = x/(x^2 + x + 1) - sage: w = 1/f*f.differential() - sage: w.cartier() == w + sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari + sage: w = 1/f*f.differential() # optional - sage.libs.pari + sage: w.cartier() == w # optional - sage.libs.pari True """ W = self.parent() @@ -559,9 +559,9 @@ class DifferentialsSpace(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: L.space_of_differentials() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: L.space_of_differentials() # optional - sage.libs.pari Space of differentials of Function field in y defined by y^3 + x^3*y + x The space of differentials is a one-dimensional module over the function @@ -571,14 +571,14 @@ class DifferentialsSpace(UniqueRepresentation, Parent): element is automatically found and used to generate the base differential relative to which other differentials are denoted:: - sage: K. = FunctionField(GF(5)) - sage: R. = K[] - sage: L. = K.extension(y^5 - 1/x) - sage: L(x).differential() + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - 1/x) # optional - sage.libs.pari + sage: L(x).differential() # optional - sage.libs.pari 0 - sage: y.differential() + sage: y.differential() # optional - sage.libs.pari d(y) - sage: (y^2).differential() + sage: (y^2).differential() # optional - sage.libs.pari (2*y) d(y) """ Element = FunctionFieldDifferential @@ -589,10 +589,10 @@ def __init__(self, field, category=None): TESTS:: - sage: K.=FunctionField(GF(4)); _.=K[] - sage: L.=K.extension(Y^3+x+x^3*Y) - sage: W = L.space_of_differentials() - sage: TestSuite(W).run() + sage: K. = FunctionField(GF(4)); _.=K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: W = L.space_of_differentials() # optional - sage.libs.pari + sage: TestSuite(W).run() # optional - sage.libs.pari """ Parent.__init__(self, base=field, category=Modules(field).FiniteDimensional().WithBasis().or_subcategory(category)) @@ -615,10 +615,10 @@ def _repr_(self): EXAMPLES:: - sage: K.=FunctionField(GF(4)); _.=K[] - sage: L.=K.extension(Y^3+x+x^3*Y) - sage: w = y.differential() - sage: w.parent() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: w = y.differential() # optional - sage.libs.pari + sage: w.parent() # optional - sage.libs.pari Space of differentials of Function field in y defined by y^3 + x^3*y + x """ return "Space of differentials of {}".format(self.base()) @@ -633,14 +633,14 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K.=FunctionField(GF(4)); _.=K[] - sage: L.=K.extension(Y^3+x+x^3*Y) - sage: S = L.space_of_differentials() - sage: S(y) + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: S = L.space_of_differentials() # optional - sage.libs.pari + sage: S(y) # optional - sage.libs.pari (x*y^2 + 1/x*y) d(x) - sage: S(y) in S + sage: S(y) in S # optional - sage.libs.pari True - sage: S(1) + sage: S(1) # optional - sage.libs.pari 0 """ if f in self.base(): @@ -675,10 +675,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: S = L.space_of_differentials() - sage: S.function_field() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: S = L.space_of_differentials() # optional - sage.libs.pari + sage: S.function_field() # optional - sage.libs.pari Function field in y defined by y^3 + x^3*y + x """ return self.base() @@ -689,10 +689,10 @@ def _an_element_(self): EXAMPLES:: - sage: K.=FunctionField(GF(4)); _.=K[] - sage: L.=K.extension(Y^3+x+x^3*Y) - sage: S = L.space_of_differentials() - sage: S.an_element() # random + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: S = L.space_of_differentials() # optional - sage.libs.pari + sage: S.an_element() # random # optional - sage.libs.pari (x*y^2 + 1/x*y) d(x) """ F = self.base() @@ -704,10 +704,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: S = L.space_of_differentials() - sage: S.basis() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: S = L.space_of_differentials() # optional - sage.libs.pari + sage: S.basis() # optional - sage.libs.pari Family (d(x),) """ return Family([self.element_class(self, self.base().one())]) @@ -723,9 +723,9 @@ class DifferentialsSpace_global(DifferentialsSpace): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: L.space_of_differentials() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: L.space_of_differentials() # optional - sage.libs.pari Space of differentials of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldDifferential_global @@ -814,12 +814,12 @@ def _call_(self, v): EXAMPLES:: - sage: K. = FunctionField(QQbar); _. = K[] - sage: L. = K.extension(Y^2 - x*Y + 4*x^3) - sage: OK = K.space_of_differentials() - sage: OL = L.space_of_differentials() - sage: mor = OL.coerce_map_from(OK) - sage: mor(x.differential()).parent() + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(Y^2 - x*Y + 4*x^3) # optional - sage.rings.number_field + sage: OK = K.space_of_differentials() # optional - sage.rings.number_field + sage: OL = L.space_of_differentials() # optional - sage.rings.number_field + sage: mor = OL.coerce_map_from(OK) # optional - sage.rings.number_field + sage: mor(x.differential()).parent() # optional - sage.rings.number_field Space of differentials of Function field in y defined by y^2 - x*y + 4*x^3 """ domain = self.domain() diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 10e06c248cd..5b41e7ee4b6 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari """ Divisors of function fields diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 6de39e743b2..574ab1fc5b2 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -20,16 +20,16 @@ Arithmetic with rational functions:: Derivatives of elements in separable extensions:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (y^3 + x).derivative() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (y^3 + x).derivative() # optional - sage.libs.pari ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 The divisor of an element of a global function field:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: y.divisor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: y.divisor() # optional - sage.libs.pari - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -387,26 +387,26 @@ cdef class FunctionFieldElement(FieldElement): sage: f.differential() (-1/t^2) d(t) - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x +1/x) - sage: (y^3 + x).differential() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari + sage: (y^3 + x).differential() # optional - sage.libs.pari (((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3) d(x) TESTS: Verify that :trac:`27712` is resolved:: - sage: K. = FunctionField(GF(31)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: R. = L[] - sage: M. = L.extension(z^2 - y) + sage: K. = FunctionField(GF(31)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: x.differential() + sage: x.differential() # optional - sage.libs.pari d(x) - sage: y.differential() + sage: y.differential() # optional - sage.libs.pari (16/x*y) d(x) - sage: z.differential() + sage: z.differential() # optional - sage.libs.pari (8/x*z) d(x) """ F = self.parent() @@ -427,9 +427,9 @@ cdef class FunctionFieldElement(FieldElement): sage: f.derivative() (-t^2 - 2*t - 1/3)/(t^4 - 2/3*t^2 + 1/9) - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (y^3 + x).derivative() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (y^3 + x).derivative() # optional - sage.libs.pari ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 """ D = self.parent().derivation() @@ -456,9 +456,9 @@ cdef class FunctionFieldElement(FieldElement): :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (y^3 + x).higher_derivative(2) + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari 1/x^3*y + (x^6 + x^4 + x^3 + x^2 + x + 1)/x^5 """ D = self.parent().higher_derivation() @@ -471,18 +471,18 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = 1/(x^3 + x^2 + x) - sage: f.divisor() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari + sage: f.divisor() # optional - sage.libs.pari 3*Place (1/x) - Place (x) - Place (x^2 + x + 1) :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: y.divisor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: y.divisor() # optional - sage.libs.pari - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -501,16 +501,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = 1/(x^3 + x^2 + x) - sage: f.divisor_of_zeros() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari + sage: f.divisor_of_zeros() # optional - sage.libs.pari 3*Place (1/x) :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (x/y).divisor_of_zeros() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari 3*Place (x, x*y) """ if self.is_zero(): @@ -527,17 +527,17 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = 1/(x^3 + x^2 + x) - sage: f.divisor_of_poles() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari + sage: f.divisor_of_poles() # optional - sage.libs.pari Place (x) + Place (x^2 + x + 1) :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (x/y).divisor_of_poles() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (x/y).divisor_of_poles() # optional - sage.libs.pari Place (1/x, 1/x*y) + 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -554,16 +554,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = 1/(x^3 + x^2 + x) - sage: f.zeros() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari + sage: f.zeros() # optional - sage.libs.pari [Place (1/x)] :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (x/y).zeros() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (x/y).zeros() # optional - sage.libs.pari [Place (x, x*y)] """ return self.divisor_of_zeros().support() @@ -574,16 +574,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = 1/(x^3 + x^2 + x) - sage: f.poles() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari + sage: f.poles() # optional - sage.libs.pari [Place (x), Place (x^2 + x + 1)] :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: (x/y).poles() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: (x/y).poles() # optional - sage.libs.pari [Place (1/x, 1/x*y), Place (x + 1, x*y)] """ return self.divisor_of_poles().support() @@ -598,10 +598,10 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_infinite()[0] - sage: y.valuation(p) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_infinite()[0] # optional - sage.libs.pari + sage: y.valuation(p) # optional - sage.libs.pari -1 :: @@ -633,23 +633,23 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(5)) - sage: p = K.place_infinite() - sage: f = 1/t^2 + 3 - sage: f.evaluate(p) + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: p = K.place_infinite() # optional - sage.libs.pari + sage: f = 1/t^2 + 3 # optional - sage.libs.pari + sage: f.evaluate(p) # optional - sage.libs.pari 3 :: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p, = L.places_infinite() - sage: p, = L.places_infinite() - sage: (y + x).evaluate(p) + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p, = L.places_infinite() # optional - sage.libs.pari + sage: p, = L.places_infinite() # optional - sage.libs.pari + sage: (y + x).evaluate(p) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: has a pole at the place - sage: (y/x + 1).evaluate(p) + sage: (y/x + 1).evaluate(p) # optional - sage.libs.pari 1 """ R, fr_R, to_R = place._residue_field() @@ -682,9 +682,9 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: f = (x+1)/(x-1) - sage: f.is_nth_power(2) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: f = (x+1)/(x-1) # optional - sage.libs.pari + sage: f.is_nth_power(2) # optional - sage.libs.pari False """ raise NotImplementedError("is_nth_power() not implemented for generic elements") @@ -708,10 +708,10 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L(y^27).nth_root(27) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L(y^27).nth_root(27) # optional - sage.libs.pari y """ raise NotImplementedError("nth_root() not implemented for generic elements") @@ -965,22 +965,22 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L(y^3).nth_root(3) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L(y^3).nth_root(3) # optional - sage.libs.pari y - sage: L(y^9).nth_root(-9) + sage: L(y^9).nth_root(-9) # optional - sage.libs.pari 1/x*y This also works for inseparable extensions:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: L. = K.extension(y^3 - x^2) - sage: L(x).nth_root(3)^3 + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - x^2) # optional - sage.libs.pari + sage: L(x).nth_root(3)^3 # optional - sage.libs.pari x - sage: L(x^9).nth_root(-27)^-27 + sage: L(x^9).nth_root(-27)^-27 # optional - sage.libs.pari x^9 """ @@ -1026,12 +1026,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: y.is_nth_power(2) + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: y.is_nth_power(2) # optional - sage.libs.pari False - sage: L(x).is_nth_power(2) + sage: L(x).is_nth_power(2) # optional - sage.libs.pari True """ @@ -1063,10 +1063,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: (y^3).nth_root(3) # indirect doctest + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: (y^3).nth_root(3) # indirect doctest # optional - sage.libs.pari y """ cdef Py_ssize_t deg = self._parent.degree() @@ -1128,7 +1128,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: ((a+1)/(a-1)).__pari__() + sage: ((a+1)/(a-1)).__pari__() # optional - sage.libs.pari (a + 1)/(a - 1) """ @@ -1366,9 +1366,9 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: f.valuation(t^2 - 1/3) -3 - sage: K. = FunctionField(GF(2)) - sage: p = K.places_finite()[0] - sage: (1/x^2).valuation(p) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: p = K.places_finite()[0] # optional - sage.libs.pari + sage: (1/x^2).valuation(p) # optional - sage.libs.pari -2 """ from .place import FunctionFieldPlace @@ -1396,10 +1396,10 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square() True - sage: K. = FunctionField(GF(5)) - sage: (-t^2).is_square() + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: (-t^2).is_square() # optional - sage.libs.pari True - sage: (-t^2).sqrt() + sage: (-t^2).sqrt() # optional - sage.libs.pari 2*t """ return self._x.is_square() @@ -1454,15 +1454,15 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: f = (x+1)/(x-1) - sage: f.is_nth_power(1) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: f = (x+1)/(x-1) # optional - sage.libs.pari + sage: f.is_nth_power(1) # optional - sage.libs.pari True - sage: f.is_nth_power(3) + sage: f.is_nth_power(3) # optional - sage.libs.pari False - sage: (f^3).is_nth_power(3) + sage: (f^3).is_nth_power(3) # optional - sage.libs.pari True - sage: (f^9).is_nth_power(-9) + sage: (f^9).is_nth_power(-9) # optional - sage.libs.pari True """ if n == 1: @@ -1505,17 +1505,17 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: f = (x+1)/(x+2) - sage: f.nth_root(1) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: f = (x+1)/(x+2) # optional - sage.libs.pari + sage: f.nth_root(1) # optional - sage.libs.pari (x + 1)/(x + 2) - sage: f.nth_root(3) + sage: f.nth_root(3) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: element is not an n-th power - sage: (f^3).nth_root(3) + sage: (f^3).nth_root(3) # optional - sage.libs.pari (x + 1)/(x + 2) - sage: (f^9).nth_root(-9) + sage: (f^9).nth_root(-9) # optional - sage.libs.pari (x + 2)/(x + 1) """ if n == 0: diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index 0abe0346f72..9b891f4fa7b 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -11,36 +11,36 @@ Constant field extension of the rational function field over rational numbers:: sage: K. = FunctionField(QQ) - sage: N. = QuadraticField(2) - sage: L = K.extension_constant_field(N) - sage: L + sage: N. = QuadraticField(2) # optional - sage.rings.number_field + sage: L = K.extension_constant_field(N) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field Rational function field in x over Number Field in a with defining polynomial x^2 - 2 with a = 1.4142... over its base - sage: d = (x^2 - 2).divisor() - sage: d + sage: d = (x^2 - 2).divisor() # optional - sage.rings.number_field + sage: d # optional - sage.rings.number_field -2*Place (1/x) + Place (x^2 - 2) - sage: L.conorm_divisor(d) + sage: L.conorm_divisor(d) # optional - sage.rings.number_field -2*Place (1/x) + Place (x - a) + Place (x + a) Constant field extension of a function field over a finite field:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) - sage: E + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari + sage: E # optional - sage.libs.pari Function field in y defined by y^3 + x^6 + x^4 + x^2 over its base - sage: p = F.get_place(3) - sage: E.conorm_place(p) # random + sage: p = F.get_place(3) # optional - sage.libs.pari + sage: E.conorm_place(p) # random # optional - sage.libs.pari Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) + Place (x + z3^2 + z3, y + z3^2) - sage: q = F.get_place(2) - sage: E.conorm_place(q) # random + sage: q = F.get_place(2) # optional - sage.libs.pari + sage: E.conorm_place(q) # random # optional - sage.libs.pari Place (x + 1, y^2 + y + 1) - sage: E.conorm_divisor(p + q) # random + sage: E.conorm_divisor(p + q) # random # optional - sage.libs.pari Place (x + 1, y^2 + y + 1) + Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) @@ -81,9 +81,9 @@ def __init__(self, F, k_ext): TESTS:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) """ k = F.constant_base_field() @@ -136,10 +136,10 @@ def defining_morphism(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) - sage: E.defining_morphism() + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari + sage: E.defining_morphism() # optional - sage.libs.pari Function Field morphism: From: Function field in y defined by y^3 + x^6 + x^4 + x^2 To: Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -161,16 +161,16 @@ def conorm_place(self, p): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) - sage: p = F.get_place(3) - sage: d = E.conorm_place(p) - sage: [pl.degree() for pl in d.support()] + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari + sage: p = F.get_place(3) # optional - sage.libs.pari + sage: d = E.conorm_place(p) # optional - sage.libs.pari + sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari [1, 1, 1] - sage: p = F.get_place(2) - sage: d = E.conorm_place(p) - sage: [pl.degree() for pl in d.support()] + sage: p = F.get_place(2) # optional - sage.libs.pari + sage: d = E.conorm_place(p) # optional - sage.libs.pari + sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari [2] """ embedF = self.defining_morphism() @@ -197,15 +197,15 @@ def conorm_divisor(self, d): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) - sage: p1 = F.get_place(3) - sage: p2 = F.get_place(2) - sage: c = E.conorm_divisor(2*p1+ 3*p2) - sage: c1 = E.conorm_place(p1) - sage: c2 = E.conorm_place(p2) - sage: c == 2*c1 + 3*c2 + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari + sage: p1 = F.get_place(3) # optional - sage.libs.pari + sage: p2 = F.get_place(2) # optional - sage.libs.pari + sage: c = E.conorm_divisor(2*p1+ 3*p2) # optional - sage.libs.pari + sage: c1 = E.conorm_place(p1) # optional - sage.libs.pari + sage: c2 = E.conorm_place(p2) # optional - sage.libs.pari + sage: c == 2*c1 + 3*c2 # optional - sage.libs.pari True """ div_top = self.divisor_group() diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 60b834221ba..22c342946f3 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -10,57 +10,57 @@ We create a rational function field:: - sage: K. = FunctionField(GF(5^2,'a')); K + sage: K. = FunctionField(GF(5^2,'a')); K # optional - sage.libs.pari Rational function field in x over Finite Field in a of size 5^2 - sage: K.genus() + sage: K.genus() # optional - sage.libs.pari 0 - sage: f = (x^2 + x + 1) / (x^3 + 1) - sage: f + sage: f = (x^2 + x + 1) / (x^3 + 1) # optional - sage.libs.pari + sage: f # optional - sage.libs.pari (x^2 + x + 1)/(x^3 + 1) - sage: f^3 + sage: f^3 # optional - sage.libs.pari (x^6 + 3*x^5 + x^4 + 2*x^3 + x^2 + 3*x + 1)/(x^9 + 3*x^6 + 3*x^3 + 1) Then we create an extension of the rational function field, and do some simple arithmetic in it:: - sage: R. = K[] - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: y^2 + sage: y^2 # optional - sage.libs.pari y^2 - sage: y^3 + sage: y^3 # optional - sage.libs.pari 2*x*y + (x^4 + 1)/x - sage: a = 1/y; a + sage: a = 1/y; a # optional - sage.libs.pari (x/(x^4 + 1))*y^2 + 3*x^2/(x^4 + 1) - sage: a * y + sage: a * y # optional - sage.libs.pari 1 We next make an extension of the above function field, illustrating that arithmetic with a tower of three fields is fully supported:: - sage: S. = L[] - sage: M. = L.extension(t^2 - x*y) - sage: M + sage: S. = L[] # optional - sage.libs.pari + sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Function field in t defined by t^2 + 4*x*y - sage: t^2 + sage: t^2 # optional - sage.libs.pari x*y - sage: 1/t + sage: 1/t # optional - sage.libs.pari ((1/(x^4 + 1))*y^2 + 3*x/(x^4 + 1))*t - sage: M.base_field() + sage: M.base_field() # optional - sage.libs.pari Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: M.base_field().base_field() + sage: M.base_field().base_field() # optional - sage.libs.pari Rational function field in x over Finite Field in a of size 5^2 It is also possible to construct function fields over an imperfect base field:: - sage: N. = FunctionField(K) + sage: N. = FunctionField(K) # optional - sage.libs.pari and inseparable extension function fields:: - sage: J. = FunctionField(GF(5)); J + sage: J. = FunctionField(GF(5)); J # optional - sage.libs.pari Rational function field in x over Finite Field of size 5 - sage: T. = J[] - sage: O. = J.extension(v^5 - x); O + sage: T. = J[] # optional - sage.libs.pari + sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari Function field in v defined by v^5 + 4*x Function fields over the rational field are supported:: @@ -99,33 +99,33 @@ Function fields over the algebraic field are supported:: - sage: K. = FunctionField(QQbar); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor() + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.number_field + sage: O = L.maximal_order() # optional - sage.rings.number_field + sage: I = O.ideal(y) # optional - sage.rings.number_field + sage: I.divisor() # optional - sage.rings.number_field Place (x - I, x*y) - Place (x, x*y) + Place (x + I, x*y) - sage: pl = I.divisor().support()[0] - sage: m = L.completion(pl, prec=5) - sage: m(x) + sage: pl = I.divisor().support()[0] # optional - sage.rings.number_field + sage: m = L.completion(pl, prec=5) # optional - sage.rings.number_field + sage: m(x) # optional - sage.rings.number_field I + s + O(s^5) - sage: m(y) # long time (4s) + sage: m(y) # long time (4s) # optional - sage.rings.number_field -2*s + (-4 - I)*s^2 + (-15 - 4*I)*s^3 + (-75 - 23*I)*s^4 + (-413 - 154*I)*s^5 + O(s^6) - sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) + sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.rings.number_field O(s^5) TESTS:: sage: TestSuite(J).run() - sage: TestSuite(K).run(max_runs=256) # long time (10s) - sage: TestSuite(L).run(max_runs=8) # long time (25s) + sage: TestSuite(K).run(max_runs=256) # long time (10s) # optional - sage.rings.number_field + sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.rings.number_field sage: TestSuite(M).run(max_runs=8) # long time (35s) sage: TestSuite(N).run(max_runs=8, skip = '_test_derivation') # long time (15s) - sage: TestSuite(O).run() + sage: TestSuite(O).run() # optional - sage.rings.number_field sage: TestSuite(R).run() - sage: TestSuite(S).run() # long time (4s) + sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.pari Global function fields ---------------------- @@ -140,31 +140,31 @@ of its maximal order and maximal infinite order, and then do arithmetic with ideals of those maximal orders:: - sage: K. = FunctionField(GF(3)); _. = K[] - sage: L. = K.extension(t^4 + t - x^5) - sage: O = L.maximal_order() - sage: O.basis() + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari (1, y, 1/x*y^2 + 1/x*y, 1/x^3*y^3 + 2/x^3*y^2 + 1/x^3*y) - sage: I = O.ideal(x,y); I + sage: I = O.ideal(x,y); I # optional - sage.libs.pari Ideal (x, y) of Maximal order of Function field in y defined by y^4 + y + 2*x^5 - sage: J = I^-1 - sage: J.basis_matrix() + sage: J = I^-1 # optional - sage.libs.pari + sage: J.basis_matrix() # optional - sage.libs.pari [ 1 0 0 0] [1/x 1/x 0 0] [ 0 0 1 0] [ 0 0 0 1] - sage: L.maximal_order_infinite().basis() + sage: L.maximal_order_infinite().basis() # optional - sage.libs.pari (1, 1/x^2*y, 1/x^3*y^2, 1/x^4*y^3) As an example of the most sophisticated computations that Sage can do with a global function field, we compute all the Weierstrass places of the Klein quartic over `\GF{2}` and gap numbers for ordinary places:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: L.genus() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari 3 - sage: L.weierstrass_places() + sage: L.weierstrass_places() # optional - sage.libs.pari, sage.modules [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -175,17 +175,17 @@ Place (x^3 + x^2 + 1, y + x), Place (x^3 + x^2 + 1, y + x^2 + 1), Place (x^3 + x^2 + 1, y + x^2 + x + 1)] - sage: L.gaps() + sage: L.gaps() # optional - sage.libs.pari, sage.modules [1, 2, 3] The gap numbers for Weierstrass places are of course not ordinary:: - sage: p1,p2,p3 = L.weierstrass_places()[:3] - sage: p1.gaps() + sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari, sage.modules + sage: p1.gaps() # optional - sage.libs.pari, sage.modules [1, 2, 4] - sage: p2.gaps() + sage: p2.gaps() # optional - sage.libs.pari, sage.modules [1, 2, 4] - sage: p3.gaps() + sage: p3.gaps() # optional - sage.libs.pari, sage.modules [1, 2, 4] AUTHORS: @@ -307,7 +307,7 @@ def is_perfect(self): sage: FunctionField(QQ, 'x').is_perfect() True - sage: FunctionField(GF(2), 'x').is_perfect() + sage: FunctionField(GF(2), 'x').is_perfect() # optional - sage.libs.pari False """ return self.characteristic() == 0 @@ -370,15 +370,15 @@ def characteristic(self): sage: K. = FunctionField(QQ) sage: K.characteristic() 0 - sage: K. = FunctionField(QQbar) - sage: K.characteristic() + sage: K. = FunctionField(QQbar) # optional - sage.rings.number_field + sage: K.characteristic() # optional - sage.rings.number_field 0 - sage: K. = FunctionField(GF(7)) - sage: K.characteristic() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.characteristic() # optional - sage.libs.pari 7 - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L.characteristic() + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L.characteristic() # optional - sage.libs.pari 7 """ return self.constant_base_field().characteristic() @@ -408,11 +408,11 @@ def is_global(self): sage: R. = FunctionField(QQ) sage: R.is_global() False - sage: R. = FunctionField(QQbar) - sage: R.is_global() + sage: R. = FunctionField(QQbar) # optional - sage.rings.number_field + sage: R.is_global() # optional - sage.rings.number_field False - sage: R. = FunctionField(GF(7)) - sage: R.is_global() + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: R.is_global() # optional - sage.libs.pari True """ return self.constant_base_field().is_finite() @@ -648,27 +648,27 @@ def _coerce_map_from_(self, source): Conversion map: From: Order in Function field in y defined by y^3 + x^3 + 4*x + 1 To: Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(GF(7)) + sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari sage: K. = FunctionField(QQ) - sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: L.has_coerce_map_from(K) + sage: L. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field + sage: L.has_coerce_map_from(K) # optional - sage.rings.number_field True sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^3 + 1) - sage: K. = FunctionField(GaussianIntegers().fraction_field()) - sage: R. = K[] - sage: M. = K.extension(y^3 + 1) - sage: M.has_coerce_map_from(L) # not tested (the constant field including into a function field is not yet known to be injective) + sage: K. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: M. = K.extension(y^3 + 1) # optional - sage.rings.number_field + sage: M.has_coerce_map_from(L) # not tested (the constant field including into a function field is not yet known to be injective) # optional - sage.rings.number_field True sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(I^2 + 1) - sage: M. = FunctionField(GaussianIntegers().fraction_field()) - sage: M.has_coerce_map_from(L) + sage: M. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field + sage: M.has_coerce_map_from(L) # optional - sage.rings.number_field True Check that :trac:`31072` is fixed:: @@ -929,10 +929,10 @@ def valuation(self, prime): Note that classical valuations at finite places or the infinite place are always normalized such that the uniformizing element has valuation 1:: - sage: K. = FunctionField(GF(3)) - sage: M. = FunctionField(K) - sage: v = M.valuation(x^3 - t) - sage: v(x^3 - t) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: M. = FunctionField(K) # optional - sage.libs.pari + sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari + sage: v(x^3 - t) # optional - sage.libs.pari 1 However, if such a valuation comes out of a base change of the ground @@ -940,16 +940,16 @@ def valuation(self, prime): extension of ``v`` to ``L`` still has valuation 1 on `x^3 - t` but it has valuation ``1/3`` on its uniformizing element `x - w`:: - sage: R. = K[] - sage: L. = K.extension(w^3 - t) - sage: N. = FunctionField(L) - sage: w = v.extension(N) # missing factorization, :trac:`16572` + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(w^3 - t) # optional - sage.libs.pari + sage: N. = FunctionField(L) # optional - sage.libs.pari + sage: w = v.extension(N) # missing factorization, :trac:`16572` # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError - sage: w(x^3 - t) # not tested + sage: w(x^3 - t) # not tested # optional - sage.libs.pari 1 - sage: w(x - w) # not tested + sage: w(x - w) # not tested # optional - sage.libs.pari 1/3 There are several ways to create valuations on extensions of rational @@ -979,10 +979,11 @@ def space_of_differentials(self): sage: K.space_of_differentials() Space of differentials of Rational function field in t over Rational Field - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.space_of_differentials() - Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.space_of_differentials() # optional - sage.libs.pari + Space of differentials of Function field in y + defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ return self._differentials_space(self) @@ -1002,15 +1003,17 @@ def space_of_holomorphic_differentials(self): From: Space of differentials of Rational function field in t over Rational Field To: Vector space of dimension 0 over Rational Field) - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.space_of_holomorphic_differentials() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari (Vector space of dimension 4 over Finite Field of size 5, Linear map: From: Vector space of dimension 4 over Finite Field of size 5 - To: Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3), + To: Space of differentials of Function field in y + defined by y^3 + (4*x^3 + 1)/(x^3 + 3), Section of linear map: - From: Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) + From: Space of differentials of Function field in y + defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Vector space of dimension 4 over Finite Field of size 5) """ return self.divisor_group().zero().differential_space() @@ -1027,9 +1030,9 @@ def basis_of_holomorphic_differentials(self): sage: K.basis_of_holomorphic_differentials() [] - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.basis_of_holomorphic_differentials() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari [((x/(x^3 + 4))*y) d(x), ((1/(x^3 + 4))*y) d(x), ((x/(x^3 + 4))*y^2) d(x), @@ -1054,9 +1057,9 @@ def divisor_group(self): sage: L.divisor_group() Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.divisor_group() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.divisor_group() # optional - sage.libs.pari Divisor group of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ from .divisor import DivisorGroup @@ -1068,17 +1071,17 @@ def place_set(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: K.place_set() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.place_set() # optional - sage.libs.pari Set of places of Rational function field in t over Finite Field of size 7 sage: K. = FunctionField(QQ) sage: K.place_set() Set of places of Rational function field in t over Rational Field - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: L.place_set() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: L.place_set() # optional - sage.libs.pari Set of places of Function field in y defined by y^2 + y + (x^2 + 1)/x """ from .place import PlaceSet @@ -1102,57 +1105,57 @@ def completion(self, place, name=None, prec=None, gen_name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p); m + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p); m # optional - sage.libs.pari Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x,10) + sage: m(x, 10) # optional - sage.libs.pari s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y,10) + sage: m(y, 10) # optional - sage.libs.pari s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p); m + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p); m # optional - sage.libs.pari Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x,10) + sage: m(x, 10) # optional - sage.libs.pari s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y,10) + sage: m(y, 10) # optional - sage.libs.pari s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) - sage: K. = FunctionField(GF(2)) - sage: p = K.places_finite()[0]; p + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: p = K.places_finite()[0]; p # optional - sage.libs.pari Place (x) - sage: m = K.completion(p); m + sage: m = K.completion(p); m # optional - sage.libs.pari Completion map: From: Rational function field in x over Finite Field of size 2 To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(1/(x+1)) + sage: m(1/(x+1)) # optional - sage.libs.pari 1 + s + s^2 + s^3 + s^4 + s^5 + s^6 + s^7 + s^8 + s^9 + s^10 + s^11 + s^12 + s^13 + s^14 + s^15 + s^16 + s^17 + s^18 + s^19 + O(s^20) - sage: p = K.place_infinite(); p + sage: p = K.place_infinite(); p # optional - sage.libs.pari Place (1/x) - sage: m = K.completion(p); m + sage: m = K.completion(p); m # optional - sage.libs.pari Completion map: From: Rational function field in x over Finite Field of size 2 To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x) + sage: m(x) # optional - sage.libs.pari s^-1 + O(s^19) - sage: m = K.completion(p, prec=infinity); m + sage: m = K.completion(p, prec=infinity); m # optional - sage.libs.pari Completion map: From: Rational function field in x over Finite Field of size 2 To: Lazy Laurent Series Ring in s over Finite Field of size 2 - sage: f = m(x); f + sage: f = m(x); f # optional - sage.libs.pari s^-1 + ... - sage: f.coefficient(100) + sage: f.coefficient(100) # optional - sage.libs.pari 0 sage: K. = FunctionField(QQ); _. = K[] @@ -1193,12 +1196,12 @@ def extension_constant_field(self, k): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^2 + Y + x + 1/x) - sage: E = F.extension_constant_field(GF(2^4)) - sage: E + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^4)) # optional - sage.libs.pari + sage: E # optional - sage.libs.pari Function field in y defined by y^2 + y + (x^2 + 1)/x over its base - sage: E.constant_base_field() + sage: E.constant_base_field() # optional - sage.libs.pari Finite Field in z4 of size 2^4 """ from .extensions import ConstantFieldExtension @@ -1652,9 +1655,9 @@ def constant_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^5 - x) - sage: L.constant_field() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^5 - x) # optional - sage.libs.pari + sage: L.constant_field() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError @@ -1792,28 +1795,28 @@ def is_separable(self, base=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L.is_separable() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari False - sage: R. = L[] - sage: M. = L.extension(z^3 - y) - sage: M.is_separable() + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari + sage: M.is_separable() # optional - sage.libs.pari True - sage: M.is_separable(K) + sage: M.is_separable(K) # optional - sage.libs.pari False - sage: K. = FunctionField(GF(5)) - sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.is_separable() + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari True - sage: K. = FunctionField(GF(5)) - sage: R. = K[] - sage: L. = K.extension(y^5 - 1) - sage: L.is_separable() + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - 1) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari False """ @@ -1976,14 +1979,14 @@ def maximal_order_infinite(self): sage: L.maximal_order_infinite() Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: F.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: L.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: L.maximal_order_infinite() # optional - sage.libs.pari Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ from .order import FunctionFieldMaximalOrderInfinite_polymod @@ -1995,9 +1998,9 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: F.different() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F.different() # optional - sage.libs.pari 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) """ @@ -2239,12 +2242,12 @@ def _simple_model(self, name='v'): Check that this also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: R. = L[] - sage: M. = L.extension(z^2-y) - sage: M._simple_model() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: M._simple_model() # optional - sage.libs.pari (Function field in v defined by v^4 + x, Function Field morphism: From: Function field in v defined by v^4 + x @@ -2259,12 +2262,12 @@ def _simple_model(self, name='v'): An example where the generator of the last extension does not generate the extension of the rational function field:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: R. = L[] - sage: M. = L.extension(z^3-1) - sage: M._simple_model() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - 1) # optional - sage.libs.pari + sage: M._simple_model() # optional - sage.libs.pari (Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1, Function Field morphism: From: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 @@ -2399,10 +2402,10 @@ def simple_model(self, name=None): An example with higher degrees:: - sage: K. = FunctionField(GF(3)); R. = K[] - sage: L. = K.extension(y^5-x); R. = L[] - sage: M. = L.extension(z^3-x) - sage: M.simple_model() + sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5-x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3-x) # optional - sage.libs.pari + sage: M.simple_model() # optional - sage.libs.pari (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3, Function Field morphism: From: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 @@ -2417,10 +2420,10 @@ def simple_model(self, name=None): This also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2-x); R. = L[] - sage: M. = L.extension(z^2-y) - sage: M.simple_model() + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2-x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2-y) # optional - sage.libs.pari + sage: M.simple_model() # optional - sage.libs.pari (Function field in z defined by z^4 + x, Function Field morphism: From: Function field in z defined by z^4 + x To: Function field in z defined by z^2 + y @@ -2490,12 +2493,12 @@ def primitive_element(self): This also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(Y^2-x) - sage: R. = L[] - sage: M. = L.extension(Z^2-y) - sage: M.primitive_element() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2-x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(Z^2-y) # optional - sage.libs.pari + sage: M.primitive_element() # optional - sage.libs.pari z """ N, f, t = self.simple_model() @@ -2531,10 +2534,10 @@ def separable_model(self, names=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x^3) - sage: L.separable_model(('t','w')) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.pari + sage: L.separable_model(('t','w')) # optional - sage.libs.pari (Function field in t defined by t^3 + w^2, Function Field morphism: From: Function field in t defined by t^3 + w^2 @@ -2549,10 +2552,10 @@ def separable_model(self, names=None): This also works for non-integral polynomials:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2/x - x^2) - sage: L.separable_model() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2/x - x^2) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari (Function field in y_ defined by y_^3 + x_^2, Function Field morphism: From: Function field in y_ defined by y_^3 + x_^2 @@ -2567,13 +2570,13 @@ def separable_model(self, names=None): If the base field is not perfect this is only implemented in trivial cases:: - sage: k. = FunctionField(GF(2)) - sage: k.is_perfect() + sage: k. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: k.is_perfect() # optional - sage.libs.pari False - sage: K. = FunctionField(k) - sage: R. = K[] - sage: L. = K.extension(y^3 - t) - sage: L.separable_model() + sage: K. = FunctionField(k) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - t) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari (Function field in y defined by y^3 + t, Function Field endomorphism of Function field in y defined by y^3 + t Defn: y |--> y @@ -2585,9 +2588,9 @@ def separable_model(self, names=None): Some other cases for which a separable model could be constructed are not supported yet:: - sage: R. = K[] - sage: L. = K.extension(y^2 - t) - sage: L.separable_model() + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - t) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError: constructing a separable model is only implemented for function fields over a perfect constant base field @@ -2610,12 +2613,12 @@ def separable_model(self, names=None): Check that this works for towers of inseparable extensions:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: R. = L[] - sage: M. = L.extension(z^2 - y) - sage: M.separable_model() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: M.separable_model() # optional - sage.libs.pari (Function field in z_ defined by z_ + x_^4, Function Field morphism: From: Function field in z_ defined by z_ + x_^4 @@ -2631,12 +2634,12 @@ def separable_model(self, names=None): Check that this also works if only the first extension is inseparable:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: R. = L[] - sage: M. = L.extension(z^3 - y) - sage: M.separable_model() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari + sage: M.separable_model() # optional - sage.libs.pari (Function field in z_ defined by z_ + x_^6, Function Field morphism: From: Function field in z_ defined by z_ + x_^6 To: Function field in z defined by z^3 + y @@ -2815,9 +2818,9 @@ def _inversion_isomorphism(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: F._inversion_isomorphism() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F._inversion_isomorphism() # optional - sage.libs.pari (Function field in s defined by s^3 + x^16 + x^14 + x^12, Composite map: From: Function field in s defined by s^3 + x^16 + x^14 + x^12 To: Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -2872,23 +2875,26 @@ def places_above(self, p): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: all(q.place_below() == p for p in K.places() for q in F.places_above(p)) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: all(q.place_below() == p # optional - sage.libs.pari + ....: for p in K.places() for q in F.places_above(p)) True sage: K. = FunctionField(QQ); _. = K[] sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) sage: O = K.maximal_order() - sage: pls = [O.ideal(x-c).place() for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p for p in pls for q in F.places_above(p)) + sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] + sage: all(q.place_below() == p + ....: for p in pls for q in F.places_above(p)) True - sage: K. = FunctionField(QQbar); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = K.maximal_order() - sage: pls = [O.ideal(x-QQbar(sqrt(c))).place() for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p # long time (4s) + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.rings.number_field + ....: for c in [-2, -1, 0, 1, 2]] + sage: all(q.place_below() == p # long time (4s) # optional - sage.rings.number_field ....: for p in pls for q in F.places_above(p)) True """ @@ -2911,9 +2917,9 @@ def constant_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(3)); _. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.constant_field() + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari + sage: L.constant_field() # optional - sage.libs.pari Finite Field of size 3 """ return self.exact_constant_field()[0] @@ -2928,17 +2934,17 @@ def exact_constant_field(self, name='t'): EXAMPLES:: - sage: K. = FunctionField(GF(3)); _. = K[] - sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible - sage: L. = K.extension(f) - sage: L.genus() + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari + sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible # optional - sage.libs.pari + sage: L. = K.extension(f) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari 0 - sage: L.exact_constant_field() + sage: L.exact_constant_field() # optional - sage.libs.pari (Finite Field in t of size 3^2, Ring morphism: From: Finite Field in t of size 3^2 To: Function field in y defined by y^2 + 2*x*y + x^2 + 1 Defn: t |--> y + x) - sage: (y+x).divisor() + sage: (y+x).divisor() # optional - sage.libs.pari 0 """ # A basis of the full constant field is obtained from @@ -2973,12 +2979,12 @@ def genus(self): EXAMPLES:: - sage: F. = GF(16) - sage: K. = FunctionField(F); K + sage: F. = GF(16) # optional - sage.libs.pari + sage: K. = FunctionField(F); K # optional - sage.libs.pari Rational function field in x over Finite Field in a of size 2^4 - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4+t-x^5) - sage: L.genus() + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari 6 The genus is computed by the Hurwitz genus formula. @@ -3012,24 +3018,24 @@ def residue_field(self, place, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: R, fr_R, to_R = L.residue_field(p) - sage: R + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: R, fr_R, to_R = L.residue_field(p) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari Finite Field of size 2 - sage: f = 1 + y - sage: f.valuation(p) + sage: f = 1 + y # optional - sage.libs.pari + sage: f.valuation(p) # optional - sage.libs.pari -1 - sage: to_R(f) + sage: to_R(f) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: ... - sage: (1+1/f).valuation(p) + sage: (1+1/f).valuation(p) # optional - sage.libs.pari 0 - sage: to_R(1 + 1/f) + sage: to_R(1 + 1/f) # optional - sage.libs.pari 1 - sage: [fr_R(e) for e in R] + sage: [fr_R(e) for e in R] # optional - sage.libs.pari [0, 1] """ return place.residue_field(name=name) @@ -3083,23 +3089,23 @@ class FunctionField_global(FunctionField_simple): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L # optional - sage.libs.pari Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) The defining equation needs not be monic:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension((1 - x)*Y^7 - x^3) - sage: L.gaps() # long time (6s) + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension((1 - x)*Y^7 - x^3) # optional - sage.libs.pari + sage: L.gaps() # long time (6s) # optional - sage.libs.pari [1, 2, 3] or may define a trivial extension:: - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y-1) - sage: L.genus() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y-1) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari 0 """ _differentials_space = DifferentialsSpace_global @@ -3110,9 +3116,9 @@ def __init__(self, polynomial, names): TESTS:: - sage: K. = FunctionField(GF(5)); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: TestSuite(L).run() # long time (7s) + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: TestSuite(L).run() # long time (7s) # optional - sage.libs.pari """ FunctionField_polymod.__init__(self, polynomial, names) @@ -3122,11 +3128,11 @@ def maximal_order(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); - sage: R. = PolynomialRing(K); - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18); - sage: O = F.maximal_order() - sage: O.basis() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari (1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y) """ from .order import FunctionFieldMaximalOrder_global @@ -3144,9 +3150,9 @@ def higher_derivation(self): EXAMPLES:: - sage: K.=FunctionField(GF(5)); _.=K[] - sage: L.=K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.higher_derivation() + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.higher_derivation() # optional - sage.libs.pari Higher derivation map: From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) @@ -3166,25 +3172,25 @@ def get_place(self, degree): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(Y^4 + Y - x^5) - sage: L.get_place(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(Y^4 + Y - x^5) # optional - sage.libs.pari + sage: L.get_place(1) # optional - sage.libs.pari Place (x, y) - sage: L.get_place(2) + sage: L.get_place(2) # optional - sage.libs.pari Place (x, y^2 + y + 1) - sage: L.get_place(3) + sage: L.get_place(3) # optional - sage.libs.pari Place (x^3 + x^2 + 1, y + x^2 + x) - sage: L.get_place(4) + sage: L.get_place(4) # optional - sage.libs.pari Place (x + 1, x^5 + 1) - sage: L.get_place(5) + sage: L.get_place(5) # optional - sage.libs.pari Place (x^5 + x^3 + x^2 + x + 1, y + x^4 + 1) - sage: L.get_place(6) + sage: L.get_place(6) # optional - sage.libs.pari Place (x^3 + x^2 + 1, y^2 + y + x^2) - sage: L.get_place(7) + sage: L.get_place(7) # optional - sage.libs.pari Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x) - sage: L.get_place(8) + sage: L.get_place(8) # optional - sage.libs.pari """ for p in self._places_finite(degree): @@ -3205,11 +3211,11 @@ def places(self, degree=1): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4 + t - x^5) - sage: L.places(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places(1) # optional - sage.libs.pari [Place (1/x, 1/x^4*y^3), Place (x, y), Place (x, y + 1)] """ return self.places_infinite(degree) + self.places_finite(degree) @@ -3224,11 +3230,11 @@ def places_finite(self, degree=1): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4+t-x^5) - sage: L.places_finite(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places_finite(1) # optional - sage.libs.pari [Place (x, y), Place (x, y + 1)] """ return list(self._places_finite(degree)) @@ -3243,11 +3249,11 @@ def _places_finite(self, degree): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4+t-x^5) - sage: L._places_finite(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L._places_finite(1) # optional - sage.libs.pari """ O = self.maximal_order() @@ -3272,11 +3278,11 @@ def places_infinite(self, degree=1): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4+t-x^5) - sage: L.places_infinite(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places_infinite(1) # optional - sage.libs.pari [Place (1/x, 1/x^4*y^3)] """ return list(self._places_infinite(degree)) @@ -3291,11 +3297,11 @@ def _places_infinite(self, degree): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: R. = PolynomialRing(K) - sage: L. = K.extension(t^4+t-x^5) - sage: L._places_infinite(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L._places_infinite(1) # optional - sage.libs.pari """ Oinf = self.maximal_order_infinite() @@ -3313,9 +3319,9 @@ def gaps(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3 * Y + x) - sage: L.gaps() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: L.gaps() # optional - sage.libs.pari, sage.modules [1, 2, 3] """ return self._weierstrass_places()[1] @@ -3326,9 +3332,9 @@ def weierstrass_places(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3 * Y + x) - sage: L.weierstrass_places() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: L.weierstrass_places() # optional - sage.libs.pari, sage.modules [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -3350,9 +3356,9 @@ def _weierstrass_places(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3 * Y + x) - sage: len(L.weierstrass_places()) # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari, sage.modules 10 This method implements Algorithm 30 in [Hes2002b]_. @@ -3397,9 +3403,9 @@ def L_polynomial(self, name='t'): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^2 + Y + x + 1/x) - sage: F.L_polynomial() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: F.L_polynomial() # optional - sage.libs.pari 2*t^2 + t + 1 """ from sage.rings.integer_ring import ZZ @@ -3429,11 +3435,11 @@ def number_of_rational_places(self, r=1): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^2 + Y + x + 1/x) - sage: F.number_of_rational_places() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: F.number_of_rational_places() # optional - sage.libs.pari 4 - sage: [F.number_of_rational_places(r) for r in [1..10]] + sage: [F.number_of_rational_places(r) for r in [1..10]] # optional - sage.libs.pari [4, 8, 4, 16, 44, 56, 116, 288, 508, 968] """ from sage.rings.integer_ring import IntegerRing @@ -3524,10 +3530,10 @@ def _maximal_order_basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = PolynomialRing(K) - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) - sage: F._maximal_order_basis() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari + sage: F._maximal_order_basis() # optional - sage.libs.pari [1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y] The basis of the maximal order *always* starts with 1. This is assumed @@ -3622,13 +3628,13 @@ def equation_order(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: F.equation_order() + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.equation_order() # optional - sage.libs.pari Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) sage: F.equation_order() Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ @@ -3648,11 +3654,11 @@ def primitive_integal_element_infinite(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: b = F.primitive_integal_element_infinite(); b + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: b = F.primitive_integal_element_infinite(); b # optional - sage.libs.pari 1/x^2*y - sage: b.minimal_polynomial('t') + sage: b.minimal_polynomial('t') # optional - sage.libs.pari t^3 + (x^4 + x^2 + 1)/x^4 """ f = self.polynomial() @@ -3675,9 +3681,9 @@ def equation_order_infinite(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: F.equation_order_infinite() + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.equation_order_infinite() # optional - sage.libs.pari Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) @@ -3721,11 +3727,11 @@ class RationalFunctionField(FunctionField): EXAMPLES:: - sage: K. = FunctionField(GF(3)); K + sage: K. = FunctionField(GF(3)); K # optional - sage.libs.pari Rational function field in t over Finite Field of size 3 - sage: K.gen() + sage: K.gen() # optional - sage.libs.pari t - sage: 1/t + t^3 + 5 + sage: 1/t + t^3 + 5 # optional - sage.libs.pari (t^4 + 2*t + 1)/t sage: K. = FunctionField(QQ); K @@ -3738,14 +3744,14 @@ class RationalFunctionField(FunctionField): There are various ways to get at the underlying fields and rings associated to a rational function field:: - sage: K. = FunctionField(GF(7)) - sage: K.base_field() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.base_field() # optional - sage.libs.pari Rational function field in t over Finite Field of size 7 - sage: K.field() + sage: K.field() # optional - sage.libs.pari Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 - sage: K.constant_field() + sage: K.constant_field() # optional - sage.libs.pari Finite Field of size 7 - sage: K.maximal_order() + sage: K.maximal_order() # optional - sage.libs.pari Maximal order of Rational function field in t over Finite Field of size 7 sage: K. = FunctionField(QQ) @@ -3778,19 +3784,19 @@ class RationalFunctionField(FunctionField): - Place (x, y + 1) + Place (x^2 + 1, y) - sage: A. = QQ[] - sage: NF. = NumberField(z^2+1) - sage: R. = FunctionField(NF) - sage: L. = R[] - sage: F. = R.extension(y^2 - (x^2+1)) + sage: A. = QQ[] # optional - sage.rings.number_field + sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: R. = FunctionField(NF) # optional - sage.rings.number_field + sage: L. = R[] # optional - sage.rings.number_field + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.rings.number_field - sage: (x/y*x.differential()).divisor() + sage: (x/y*x.differential()).divisor() # optional - sage.rings.number_field -2*Place (1/x, 1/x*y - 1) - 2*Place (1/x, 1/x*y + 1) + Place (x, y - 1) + Place (x, y + 1) - sage: (x/y).divisor() + sage: (x/y).divisor() # optional - sage.rings.number_field - Place (x - i, y) + Place (x, y - 1) + Place (x, y + 1) @@ -3809,8 +3815,9 @@ def __init__(self, constant_field, names, category=None): Rational function field in t over Complex Field with 53 bits of precision sage: TestSuite(K).run() # long time (5s) - sage: FunctionField(QQ[I], 'alpha') - Rational function field in alpha over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: FunctionField(QQ[I], 'alpha') # optional - sage.rings.number_field + Rational function field in alpha over + Number Field in I with defining polynomial x^2 + 1 with I = 1*I Must be over a field:: @@ -4009,10 +4016,10 @@ def _to_bivariate_polynomial(self, f): EXAMPLES:: - sage: R. = FunctionField(GF(7)) - sage: S. = R[] - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) - sage: R._to_bivariate_polynomial(f) + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari + sage: R._to_bivariate_polynomial(f) # optional - sage.libs.pari (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) """ v = f.list() @@ -4044,34 +4051,34 @@ def _factor_univariate_polynomial(self, f, proof=None): We do a factorization over a finite prime field:: - sage: R. = FunctionField(GF(7)) - sage: S. = R[] - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) - sage: f.factor() + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari + sage: f.factor() # optional - sage.libs.pari (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t) - sage: f.factor().prod() == f + sage: f.factor().prod() == f # optional - sage.libs.pari True Factoring over a function field over a non-prime finite field:: - sage: k. = GF(9) - sage: R. = FunctionField(k) - sage: S. = R[] - sage: f = (1/t)*(X^3 - a*t^3) - sage: f.factor() + sage: k. = GF(9) # optional - sage.libs.pari + sage: R. = FunctionField(k) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^3 - a*t^3) # optional - sage.libs.pari + sage: f.factor() # optional - sage.libs.pari (1/t) * (X + (a + 2)*t)^3 - sage: f.factor().prod() == f + sage: f.factor().prod() == f # optional - sage.libs.pari True Factoring over a function field over a tower of finite fields:: - sage: k. = GF(4) - sage: R. = k[] - sage: l. = k.extension(b^2 + b + a) - sage: K. = FunctionField(l) - sage: R. = K[] - sage: F = t*x - sage: F.factor(proof=False) + sage: k. = GF(4) # optional - sage.libs.pari + sage: R. = k[] # optional - sage.libs.pari + sage: l. = k.extension(b^2 + b + a) # optional - sage.libs.pari + sage: K. = FunctionField(l) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: F = t*x # optional - sage.libs.pari + sage: F.factor(proof=False) # optional - sage.libs.pari (x) * t """ @@ -4295,8 +4302,8 @@ def base_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: K.base_field() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.base_field() # optional - sage.libs.pari Rational function field in t over Finite Field of size 7 """ return self @@ -4322,24 +4329,24 @@ def hom(self, im_gens, base_morphism=None): We make a map from a rational function field to itself:: - sage: K. = FunctionField(GF(7)) - sage: K.hom( (x^4 + 2)/x) + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.hom( (x^4 + 2)/x) # optional - sage.libs.pari Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> (x^4 + 2)/x We construct a map from a rational function field into a non-rational extension field:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x) - sage: f = K.hom(y^2 + y + 2); f + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari Function Field morphism: From: Rational function field in x over Finite Field of size 7 To: Function field in y defined by y^3 + 6*x^3 + x Defn: x |--> y^2 + y + 2 - sage: f(x) + sage: f(x) # optional - sage.libs.pari y^2 + y + 2 - sage: f(x^2) + sage: f(x^2) # optional - sage.libs.pari 5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4 """ if isinstance(im_gens, CategoryObject): @@ -4362,8 +4369,8 @@ def field(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: K.field() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.field() # optional - sage.libs.pari Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 .. SEEALSO:: @@ -4515,12 +4522,12 @@ def residue_field(self, place, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: p = F.places_finite(2)[0] - sage: R, fr_R, to_R = F.residue_field(p) - sage: R + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: p = F.places_finite(2)[0] # optional - sage.libs.pari + sage: R, fr_R, to_R = F.residue_field(p) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari Finite Field in z2 of size 5^2 - sage: to_R(x) in R + sage: to_R(x) in R # optional - sage.libs.pari True """ return place.residue_field(name=name) @@ -4566,8 +4573,8 @@ def places(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: F.places() + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari [Place (1/x), Place (x), Place (x + 1), @@ -4590,8 +4597,8 @@ def places_finite(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: F.places_finite() + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.places_finite() # optional - sage.libs.pari [Place (x), Place (x + 1), Place (x + 2), Place (x + 3), Place (x + 4)] """ return list(self._places_finite(degree)) @@ -4606,8 +4613,8 @@ def _places_finite(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: F._places_finite() + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F._places_finite() # optional - sage.libs.pari """ O = self.maximal_order() @@ -4625,8 +4632,8 @@ def place_infinite(self): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: F.place_infinite() + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.place_infinite() # optional - sage.libs.pari Place (1/x) """ return self.maximal_order_infinite().prime_ideal().place() @@ -4641,17 +4648,17 @@ def get_place(self, degree): EXAMPLES:: - sage: F. = GF(2) - sage: K. = FunctionField(F) - sage: K.get_place(1) + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: K.get_place(1) # optional - sage.libs.pari Place (x) - sage: K.get_place(2) + sage: K.get_place(2) # optional - sage.libs.pari Place (x^2 + x + 1) - sage: K.get_place(3) + sage: K.get_place(3) # optional - sage.libs.pari Place (x^3 + x + 1) - sage: K.get_place(4) + sage: K.get_place(4) # optional - sage.libs.pari Place (x^4 + x + 1) - sage: K.get_place(5) + sage: K.get_place(5) # optional - sage.libs.pari Place (x^5 + x^2 + 1) """ @@ -4669,11 +4676,11 @@ def higher_derivation(self): EXAMPLES:: - sage: F. = FunctionField(GF(5)) - sage: d = F.higher_derivation() - sage: [d(x^5,i) for i in range(10)] + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: d = F.higher_derivation() # optional - sage.libs.pari + sage: [d(x^5,i) for i in range(10)] # optional - sage.libs.pari [x^5, 0, 0, 0, 0, 1, 0, 0, 0, 0] - sage: [d(x^7,i) for i in range(10)] + sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] """ from .maps import RationalFunctionFieldHigherDerivation_global diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index 2573df22267..f7348440bbf 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -78,10 +78,10 @@ Run test suite for some other classical places over large ground fields:: - sage: K. = FunctionField(GF(3)) - sage: M. = FunctionField(K) - sage: v = M.valuation(x^3 - t) - sage: TestSuite(v).run(max_runs=10) # long time + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: M. = FunctionField(K) # optional - sage.libs.pari + sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari + sage: TestSuite(v).run(max_runs=10) # long time # optional - sage.libs.pari Run test suite for extensions over the infinite place:: @@ -112,9 +112,9 @@ Run test suite for a finite place with residual degree and ramification:: - sage: K. = FunctionField(GF(3)) - sage: L. = FunctionField(K) - sage: v = L.valuation(x^6 - t) + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: L. = FunctionField(K) # optional - sage.libs.pari + sage: v = L.valuation(x^6 - t) # optional - sage.libs.pari sage: TestSuite(v).run(max_runs=10) # long time Run test suite for a valuation which is backed by limit valuation:: @@ -351,11 +351,11 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v TESTS:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari """ from sage.categories.function_fields import FunctionFields @@ -509,14 +509,14 @@ def extensions(self, L): Iterated extensions over the infinite place:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) - sage: R. = L[] - sage: M. = L.extension(z^2 - y) - sage: w.extension(M) # squarefreeness is not implemented here + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError @@ -536,13 +536,13 @@ def extensions(self, L): Test that this works in towers:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y - x) - sage: R. = L[] - sage: L. = L.extension(z - y) - sage: v = K.valuation(x) - sage: v.extensions(L) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: L. = L.extension(z - y) # optional - sage.libs.pari + sage: v = K.valuation(x) # optional - sage.libs.pari + sage: v.extensions(L) # optional - sage.libs.pari [(x)-adic valuation] """ K = self.domain() @@ -587,10 +587,10 @@ class RationalFunctionFieldValuation_base(FunctionFieldValuation_base): TESTS:: - sage: K. = FunctionField(GF(2)) - sage: v = K.valuation(x) # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari sage: from sage.rings.function_field.function_field_valuation import RationalFunctionFieldValuation_base - sage: isinstance(v, RationalFunctionFieldValuation_base) + sage: isinstance(v, RationalFunctionFieldValuation_base) # optional - sage.libs.pari True """ @@ -630,10 +630,10 @@ class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base): TESTS:: - sage: K. = FunctionField(GF(5)) - sage: v = K.valuation(x) # indirect doctest + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari sage: from sage.rings.function_field.function_field_valuation import ClassicalFunctionFieldValuation_base - sage: isinstance(v, ClassicalFunctionFieldValuation_base) + sage: isinstance(v, ClassicalFunctionFieldValuation_base) # optional - sage.libs.pari True """ @@ -998,14 +998,14 @@ class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation A finite place with ramification:: - sage: K. = FunctionField(GF(3)) - sage: L. = FunctionField(K) - sage: u = L.valuation(x^3 - t); u + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: L. = FunctionField(K) # optional - sage.libs.pari + sage: u = L.valuation(x^3 - t); u # optional - sage.libs.pari (x^3 + 2*t)-adic valuation A finite place with residual degree and ramification:: - sage: q = L.valuation(x^6 - t); q + sage: q = L.valuation(x^6 - t); q # optional - sage.libs.pari (x^6 + 2*t)-adic valuation """ @@ -1176,8 +1176,8 @@ class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValua EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: v = K.valuation(1/x); v + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x); v # optional - sage.libs.pari Valuation at the infinite place """ @@ -1185,10 +1185,10 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v r""" TESTS:: - sage: K. = FunctionField(GF(2)) - sage: v = K.valuation(1/x) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage: from sage.rings.function_field.function_field_valuation import FunctionFieldMappedValuation_base - sage: isinstance(v, FunctionFieldMappedValuation_base) + sage: isinstance(v, FunctionFieldMappedValuation_base) # optional - sage.libs.pari True """ @@ -1204,12 +1204,12 @@ def _to_base_domain(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) - sage: w._to_base_domain(y) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w._to_base_domain(y) # optional - sage.libs.pari x^2*y """ @@ -1221,12 +1221,12 @@ def _from_base_domain(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) - sage: w._from_base_domain(w._to_base_domain(y)) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari y r""" @@ -1238,12 +1238,12 @@ def scale(self, scalar): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) - sage: 3*w + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: 3*w # optional - sage.libs.pari 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) """ @@ -1258,11 +1258,11 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: v.extension(L) # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: v.extension(L) # indirect doctest # optional - sage.libs.pari Valuation at the infinite place """ @@ -1297,8 +1297,8 @@ class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_bas EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: v = K.valuation(1/x); v + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x); v # optional - sage.libs.pari Valuation at the infinite place """ @@ -1306,10 +1306,10 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v r""" TESTS:: - sage: K. = FunctionField(GF(2)) - sage: v = K.valuation(1/x) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage: from sage.rings.function_field.function_field_valuation import FunctionFieldMappedValuationRelative_base - sage: isinstance(v, FunctionFieldMappedValuationRelative_base) + sage: isinstance(v, FunctionFieldMappedValuationRelative_base) # optional - sage.libs.pari True """ @@ -1323,8 +1323,8 @@ def restriction(self, ring): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: K.valuation(1/x).restriction(GF(2)) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: K.valuation(1/x).restriction(GF(2)) # optional - sage.libs.pari Trivial valuation on Finite Field of size 2 """ @@ -1416,17 +1416,17 @@ class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari - sage: w(x) + sage: w(x) # optional - sage.libs.pari -1 - sage: w(y) + sage: w(y) # optional - sage.libs.pari -3/2 - sage: w.uniformizer() + sage: w.uniformizer() # optional - sage.libs.pari 1/x^2*y TESTS:: @@ -1442,11 +1442,11 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L); w + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L); w # optional - sage.libs.pari Valuation at the infinite place sage: K. = FunctionField(QQ) @@ -1469,12 +1469,12 @@ def restriction(self, ring): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 + y + x^3) - sage: v = K.valuation(1/x) - sage: w = v.extension(L) - sage: w.restriction(K) is v + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w.restriction(K) is v # optional - sage.libs.pari True """ if ring.is_subring(self.domain().base()): diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 1ce0b885f56..a9a574bed90 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -35,37 +35,37 @@ Ideals in the maximal order of a global function field:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I^2 + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I^2 # optional - sage.libs.pari Ideal (x) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I + sage: ~I # optional - sage.libs.pari Ideal (1/x*y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I * I + sage: ~I * I # optional - sage.libs.pari Ideal (1) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J = O.ideal(x+y) * I - sage: J.factor() + sage: J = O.ideal(x+y) * I # optional - sage.libs.pari + sage: J.factor() # optional - sage.libs.pari (Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x)^2 * (Ideal (x^3 + x + 1, y + x) of Maximal order of Function field in y defined by y^2 + x^3*y + x) Ideals in the maximal infinite order of a global function field:: - sage: K. = FunctionField(GF(3^2)); R. = K[] - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: I + I == I + sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: I + I == I # optional - sage.libs.pari True - sage: I^2 + sage: I^2 # optional - sage.libs.pari Ideal (1/x^4*y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I + sage: ~I # optional - sage.libs.pari Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I * I + sage: ~I * I # optional - sage.libs.pari Ideal (1) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: I.factor() + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^4 AUTHORS: @@ -125,9 +125,9 @@ class FunctionFieldIdeal(Element): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: O = K.equation_order() - sage: O.ideal(x^3+1) + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.equation_order() # optional - sage.libs.pari + sage: O.ideal(x^3 + 1) # optional - sage.libs.pari Ideal (x^3 + 1) of Maximal order of Rational function field in x over Finite Field of size 7 """ def __init__(self, ring): @@ -136,10 +136,10 @@ def __init__(self, ring): TESTS:: - sage: K. = FunctionField(GF(7)) - sage: O = K.equation_order() - sage: I = O.ideal(x^3+1) - sage: TestSuite(I).run() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.equation_order() # optional - sage.libs.pari + sage: I = O.ideal(x^3 + 1) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari """ Element.__init__(self, ring.ideal_monoid()) self._ring = ring @@ -151,11 +151,11 @@ def _repr_short(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = K[] - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: I._repr_short() + sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: I._repr_short() # optional - sage.libs.pari '(1/x^4*y^2)' """ if self.is_zero(): @@ -180,36 +180,36 @@ def _repr_(self): sage: O.ideal(x^2 + 1) Ideal (x^2 + 1) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y); I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y); I + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2+1)) - sage: I + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: I # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.ideal(1/y) + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(1/y) # optional - sage.libs.pari Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.ideal(1/y) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(1/y) # optional - sage.libs.pari Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -224,11 +224,11 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: latex(I) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: latex(I) # optional - sage.libs.pari \left(y\right) """ return '\\left(' + ', '.join(latex(g) for g in self.gens_reduced()) + '\\right)' @@ -243,10 +243,10 @@ def _div_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: O = K.equation_order() - sage: I = O.ideal(x^3+1) - sage: I / I + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.equation_order() # optional - sage.libs.pari + sage: I = O.ideal(x^3+1) # optional - sage.libs.pari + sage: I / I # optional - sage.libs.pari Ideal (1) of Maximal order of Rational function field in x over Finite Field of size 7 """ @@ -267,10 +267,10 @@ def gens_reduced(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: O = K.equation_order() - sage: I = O.ideal(x,x^2,x^2+x) - sage: I.gens_reduced() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.equation_order() # optional - sage.libs.pari + sage: I = O.ideal(x, x^2, x^2+x) # optional - sage.libs.pari + sage: I.gens_reduced() # optional - sage.libs.pari (x,) """ gens = self.gens() @@ -289,10 +289,10 @@ def ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: O = K.equation_order() - sage: I = O.ideal(x,x^2,x^2+x) - sage: I.ring() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.equation_order() # optional - sage.libs.pari + sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.libs.pari + sage: I.ring() # optional - sage.libs.pari Maximal order of Rational function field in x over Finite Field of size 7 """ return self._ring @@ -318,63 +318,63 @@ def place(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^2 + x + 1) - sage: I.place() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: I.place() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: not a prime ideal - sage: I = O.ideal(x^3+x+1) - sage: I.place() + sage: I = O.ideal(x^3+x+1) # optional - sage.libs.pari + sage: I.place() # optional - sage.libs.pari Place (x^3 + x + 1) - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) - sage: p = I.factor()[0][0] - sage: p.place() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari + sage: p = I.factor()[0][0] # optional - sage.libs.pari + sage: p.place() # optional - sage.libs.pari Place (1/x) - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: [f.place() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari [Place (x, (1/(x^3 + x^2 + x))*y^2), Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2)] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: [f.place() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari [Place (x, x*y), Place (x + 1, x*y)] - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True - sage: J.place() + sage: J.place() # optional - sage.libs.pari Place (1/x, 1/x^3*y^2) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True - sage: J.place() + sage: J.place() # optional - sage.libs.pari Place (1/x, 1/x*y) """ if not self.is_prime(): @@ -392,32 +392,32 @@ def factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^3*(x + 1)^2) - sage: I.factor() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^3*(x + 1)^2) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (x) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^3 * (Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^2 - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) - sage: I.factor() + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field in z2 of size 2^2)^2 - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I == I.factor().prod() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I == I.factor().prod() # optional - sage.libs.pari True - sage: Oinf = F.maximal_order_infinite() - sage: f= 1/x - sage: I = Oinf.ideal(f) - sage: I.factor() + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: f= 1/x # optional - sage.libs.pari + sage: I = Oinf.ideal(f) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2) * (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order @@ -446,42 +446,42 @@ def divisor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) - sage: I.divisor() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari Place (x) + 2*Place (x + 1) - Place (x + z2) - Place (x + z2 + 1) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) - sage: I.divisor() + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari 2*Place (1/x) - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(y) - sage: I.divisor() + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(y) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari -2*Place (1/x, 1/x^4*y^2 + 1/x^2*y + 1) - 2*Place (1/x, 1/x^2*y + 1) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari - Place (x, x*y) + 2*Place (x + 1, x*y) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(y) - sage: I.divisor() + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(y) # optional - sage.libs.pari + sage: I.divisor() # optional - sage.libs.pari - Place (1/x, 1/x*y) """ if self.is_zero(): @@ -497,23 +497,23 @@ def divisor_of_zeros(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) - sage: I.divisor_of_zeros() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari + sage: I.divisor_of_zeros() # optional - sage.libs.pari Place (x) + 2*Place (x + 1) - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) - sage: I.divisor_of_zeros() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari + sage: I.divisor_of_zeros() # optional - sage.libs.pari 2*Place (1/x) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor_of_zeros() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I.divisor_of_zeros() # optional - sage.libs.pari 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -529,23 +529,23 @@ def divisor_of_poles(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) - sage: I.divisor_of_poles() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari + sage: I.divisor_of_poles() # optional - sage.libs.pari Place (x + z2) + Place (x + z2 + 1) - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) - sage: I.divisor_of_poles() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari + sage: I.divisor_of_poles() # optional - sage.libs.pari 0 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor_of_poles() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I.divisor_of_poles() # optional - sage.libs.pari Place (x, x*y) """ if self.is_zero(): @@ -776,10 +776,10 @@ def gen(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^2+x) - sage: I.gen() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gen() # optional - sage.libs.pari x^2 + x """ return self._gen @@ -790,10 +790,10 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^2+x) - sage: I.gens() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^2 + x,) """ return (self._gen,) @@ -805,10 +805,10 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^2+x) - sage: I.gens_over_base() + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari (x^2 + x,) """ return (self._gen,) @@ -867,10 +867,10 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) - sage: O = K.maximal_order() - sage: I = O.ideal(x^3*(x+1)^2) - sage: I.factor() # indirect doctest + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^3*(x+1)^2) # optional - sage.libs.pari + sage: I.factor() # indirect doctest # optional - sage.libs.pari (Ideal (x) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^3 * (Ideal (x + 1) of Maximal order of Rational function field in x @@ -1187,10 +1187,10 @@ class FunctionFieldIdeal_polymod(FunctionFieldIdeal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: O.ideal(y) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.ideal(y) # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x """ def __init__(self, ring, hnf, denominator=1): @@ -1199,11 +1199,11 @@ def __init__(self, ring, hnf, denominator=1): TESTS:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: TestSuite(I).run() + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari """ FunctionFieldIdeal.__init__(self, ring) @@ -1239,29 +1239,29 @@ def __bool__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y); I + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: I.is_zero() + sage: I.is_zero() # optional - sage.libs.pari False - sage: J = 0*I; J + sage: J = 0*I; J # optional - sage.libs.pari Zero ideal of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J.is_zero() + sage: J.is_zero() # optional - sage.libs.pari True - sage: K.=FunctionField(GF(2)); _.=K[] - sage: L.=K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y); I + sage: K.=FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari + sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I.is_zero() + sage: I.is_zero() # optional - sage.libs.pari False - sage: J = 0*I; J + sage: J = 0*I; J # optional - sage.libs.pari Zero ideal of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: J.is_zero() + sage: J.is_zero() # optional - sage.libs.pari True """ return self._hnf.nrows() != 0 @@ -1274,17 +1274,17 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(1/y) - sage: { I: 2 }[I] == 2 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: { I: 2 }[I] == 2 # optional - sage.libs.pari True - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(1/y) - sage: { I: 2 }[I] == 2 + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: { I: 2 }[I] == 2 # optional - sage.libs.pari True """ return hash((self._ring, self._hnf, self._denominator)) @@ -1295,30 +1295,30 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(7)); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal([y]); I + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal([y]); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: x * y in I + sage: x * y in I # optional - sage.libs.pari True - sage: y / x in I + sage: y / x in I # optional - sage.libs.pari False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.pari False - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal([y]); I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal([y]); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I + sage: x * y in I # optional - sage.libs.pari True - sage: y / x in I + sage: y / x in I # optional - sage.libs.pari False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.pari False sage: K. = FunctionField(QQ); _. = K[] @@ -1362,30 +1362,30 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: ~I + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I^(-1) + sage: I^(-1) # optional - sage.libs.pari Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: ~I * I + sage: ~I * I # optional - sage.libs.pari Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: ~I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) + sage: I^(-1) # optional - sage.libs.pari Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I + sage: ~I * I # optional - sage.libs.pari Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x :: @@ -1434,28 +1434,28 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(1/y) - sage: I == I + I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I == I + I # optional - sage.libs.pari True - sage: I == I * I + sage: I == I * I # optional - sage.libs.pari False :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(1/y) - sage: I == I + I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I == I + I # optional - sage.libs.pari True - sage: I == I * I + sage: I == I * I # optional - sage.libs.pari False - sage: I < I * I + sage: I < I * I # optional - sage.libs.pari True - sage: I > I * I + sage: I > I * I # optional - sage.libs.pari False """ return richcmp((self._denominator, self._hnf), (other._denominator, other._hnf), op) @@ -1466,19 +1466,19 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I + J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I + J + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari Ideal (1, y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ ds = self._denominator @@ -1493,20 +1493,20 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I * J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari Ideal (x^4 + x^2 + x, x*y + x^2) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I * J + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari Ideal ((x + 1)*y + (x^2 + 1)/x) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1544,19 +1544,19 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: J = O.ideal(x) - sage: x * I == I * J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: x * I == I * J # optional - sage.libs.pari True - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: J = O.ideal(x) - sage: x * I == I * J + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: x * I == I * J # optional - sage.libs.pari True """ O = self._ring @@ -1582,12 +1582,12 @@ def intersect(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: J = O.ideal(x) - sage: I.intersect(J) == I * J * (I + J)^-1 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.libs.pari True """ @@ -1626,10 +1626,10 @@ def hnf(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y*(y+1)); I.hnf() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.pari [x^6 + x^3 0] [ x^3 + 1 1] @@ -1650,13 +1650,13 @@ def denominator(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y/(y+1)) - sage: d = I.denominator(); d + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y/(y+1)) # optional - sage.libs.pari + sage: d = I.denominator(); d # optional - sage.libs.pari x^3 - sage: d in O + sage: d in O # optional - sage.libs.pari True :: @@ -1680,11 +1680,11 @@ def module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: F. = K.extension(y^2 - x^3 - 1) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.module() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.module() # optional - sage.libs.pari Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -1704,17 +1704,17 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens_over_base() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens_over_base() + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari (x^3 + 1, y + x) """ gens, d = self._gens_over_base @@ -1728,11 +1728,11 @@ def _gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(1/y) - sage: I._gens_over_base + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I._gens_over_base # optional - sage.libs.pari ([x, y], x) """ gens = [] @@ -1749,17 +1749,17 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 +Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens() + sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^3 + 1, y + x) """ return self.gens_over_base() @@ -1774,11 +1774,11 @@ def basis_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.denominator() * I.basis_matrix() == I.hnf() + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.libs.pari True """ d = self.denominator() @@ -1794,24 +1794,24 @@ def is_integral(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.is_integral() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.is_integral() # optional - sage.libs.pari False - sage: J = I.denominator() * I - sage: J.is_integral() + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.is_integral() # optional - sage.libs.pari True - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.is_integral() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.is_integral() # optional - sage.libs.pari False - sage: J = I.denominator() * I - sage: J.is_integral() + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.is_integral() # optional - sage.libs.pari True sage: K. = FunctionField(QQ); _. = PolynomialRing(K) @@ -1834,29 +1834,29 @@ def ideal_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.ideal_below() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I - sage: J.ideal_below() + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.ideal_below() # optional - sage.libs.pari Ideal (x^3 + x^2 + x) of Maximal order of Rational function field in x over Finite Field of size 2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.ideal_below() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I - sage: J.ideal_below() + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.ideal_below() # optional - sage.libs.pari Ideal (x^3 + x) of Maximal order of Rational function field in x over Finite Field of size 2 @@ -1900,38 +1900,38 @@ def norm(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: i1 = O.ideal(x) - sage: i2 = O.ideal(y) - sage: i3 = i1 * i2 - sage: i3.norm() == i1.norm() * i2.norm() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i1 = O.ideal(x) # optional - sage.libs.pari + sage: i2 = O.ideal(y) # optional - sage.libs.pari + sage: i3 = i1 * i2 # optional - sage.libs.pari + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari True - sage: i1.norm() + sage: i1.norm() # optional - sage.libs.pari x^3 - sage: i1.norm() == x ** F.degree() + sage: i1.norm() == x ** F.degree() # optional - sage.libs.pari True - sage: i2.norm() + sage: i2.norm() # optional - sage.libs.pari x^6 + x^4 + x^2 - sage: i2.norm() == y.norm() + sage: i2.norm() == y.norm() # optional - sage.libs.pari True - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: i1 = O.ideal(x) - sage: i2 = O.ideal(y) - sage: i3 = i1 * i2 - sage: i3.norm() == i1.norm() * i2.norm() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: i1 = O.ideal(x) # optional - sage.libs.pari + sage: i2 = O.ideal(y) # optional - sage.libs.pari + sage: i3 = i1 * i2 # optional - sage.libs.pari + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari True - sage: i1.norm() + sage: i1.norm() # optional - sage.libs.pari x^2 - sage: i1.norm() == x ** L.degree() + sage: i1.norm() == x ** L.degree() # optional - sage.libs.pari True - sage: i2.norm() + sage: i2.norm() # optional - sage.libs.pari (x^2 + 1)/x - sage: i2.norm() == y.norm() + sage: i2.norm() == y.norm() # optional - sage.libs.pari True """ n = 1 @@ -1946,18 +1946,18 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: [f.is_prime() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari [True, True] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: [f.is_prime() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari [True, True] sage: K. = FunctionField(QQ); _. = PolynomialRing(K) @@ -1994,21 +1994,21 @@ def valuation(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) - sage: I.is_prime() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.libs.pari True - sage: J = O.ideal(y) - sage: I.valuation(J) + sage: J = O.ideal(y) # optional - sage.libs.pari + sage: I.valuation(J) # optional - sage.libs.pari 2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: [f.valuation(I) for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari [-1, 2] The method closely follows Algorithm 4.8.17 of [Coh1993]_. @@ -2061,20 +2061,20 @@ def prime_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: [f.prime_below() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: [f.prime_below() for f,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] @@ -2094,11 +2094,11 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I == I.factor().prod() # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I == I.factor().prod() # indirect doctest # optional - sage.libs.pari True """ O = self.ring() @@ -2137,10 +2137,10 @@ class FunctionFieldIdeal_global(FunctionFieldIdeal_polymod): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: O.ideal(y) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.ideal(y) # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x """ def __init__(self, ring, hnf, denominator=1): @@ -2149,11 +2149,11 @@ def __init__(self, ring, hnf, denominator=1): TESTS:: - sage: K. = FunctionField(GF(5)); R. = K[] - sage: L. = K.extension(y^2 - x^3*y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: TestSuite(I).run() + sage: K. = FunctionField(GF(5)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari """ FunctionFieldIdeal_polymod.__init__(self, ring, hnf, denominator) @@ -2166,18 +2166,18 @@ def __pow__(self, mod): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^7 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x + y) - sage: S = I / J - sage: a = S^100 - sage: _ = S.gens_two() - sage: b = S^100 # faster - sage: b == I^100 / J^100 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^7 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari + sage: S = I / J # optional - sage.libs.pari + sage: a = S^100 # optional - sage.libs.pari + sage: _ = S.gens_two() # optional - sage.libs.pari + sage: b = S^100 # faster # optional - sage.libs.pari + sage: b == I^100 / J^100 # optional - sage.libs.pari True - sage: b == a + sage: b == a # optional - sage.libs.pari True """ if mod > 2 and self._gens_two_vecs is not None: @@ -2212,17 +2212,17 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 - x^3*Y - x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 +Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(x+y) - sage: I.gens() + sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^3 + 1, y + x) """ if self._gens_two.is_in_cache(): @@ -2238,25 +2238,25 @@ def gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I # indirect doctest # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: ~I # indirect doctest + sage: ~I # indirect doctest # optional - sage.libs.pari Ideal ((1/(x^6 + x^4 + x^2))*y^2) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I # indirect doctest # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I # indirect doctest + sage: ~I # indirect doctest # optional - sage.libs.pari Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2291,17 +2291,17 @@ def _gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: F. = K.extension(Y^3 + x^3*Y + x) - sage: O = F.maximal_order() - sage: I = O.ideal(x^2,x*y,x+y) - sage: I._gens_two() + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2,x*y,x+y) # optional - sage.libs.pari + sage: I._gens_two() # optional - sage.libs.pari (x, y) - sage: K. = FunctionField(GF(3)) - sage: _. = K[] - sage: L. = K.extension(Y-x) - sage: y.zeros()[0].prime_ideal()._gens_two() + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y-x) # optional - sage.libs.pari + sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.libs.pari (x,) """ O = self.ring() @@ -2411,9 +2411,9 @@ class FunctionFieldIdealInfinite_rational(FunctionFieldIdealInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: Oinf.ideal(x) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(x) # optional - sage.libs.pari Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ def __init__(self, ring, gen): @@ -2422,10 +2422,10 @@ def __init__(self, ring, gen): TESTS:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x) - sage: TestSuite(I).run() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari """ FunctionFieldIdealInfinite.__init__(self, ring) self._gen = gen @@ -2436,11 +2436,11 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x) - sage: J = Oinf.ideal(1/x) - sage: d = { I: 1, J: 2 } + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: d = { I: 1, J: 2 } # optional - sage.libs.pari """ return hash( (self.ring(), self._gen) ) @@ -2474,11 +2474,11 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x+1) - sage: J = Oinf.ideal(x^2+x) - sage: I + J == J + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+1) # optional - sage.libs.pari + sage: J = Oinf.ideal(x^2+x) # optional - sage.libs.pari + sage: I + J == J # optional - sage.libs.pari True """ return richcmp(self._gen, other._gen, op) @@ -2493,11 +2493,11 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2+1)) - sage: J = Oinf.ideal(1/(x+1)) - sage: I + J + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -2513,11 +2513,11 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2+1)) - sage: J = Oinf.ideal(1/(x+1)) - sage: I * J + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari Ideal (1/x^2) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -2533,10 +2533,10 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2+1)) - sage: x * I + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: x * I # optional - sage.libs.pari Ideal (1) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -2548,10 +2548,10 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2 + 1)) - sage: ~I # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari + sage: ~I # indirect doctest # optional - sage.libs.pari Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -2563,10 +2563,10 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal(x/(x^2 + 1)) - sage: I.is_prime() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.libs.pari True """ x = self._ring.fraction_field().gen() @@ -2578,10 +2578,10 @@ def gen(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) - sage: I.gen() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gen() # optional - sage.libs.pari 1/x^2 """ return self._gen @@ -2592,10 +2592,10 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) - sage: I.gens() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (1/x^2,) """ return (self._gen,) @@ -2607,10 +2607,10 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) - sage: I.gens_over_base() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari (1/x^2,) """ return (self._gen,) @@ -2648,10 +2648,10 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: Oinf = K.maximal_order_infinite() - sage: I = Oinf.ideal((x+1)/(x^3+1)) - sage: I._factor() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+1)) # optional - sage.libs.pari + sage: I._factor() # optional - sage.libs.pari [(Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2, 2)] """ @@ -2716,16 +2716,16 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([1, y]); I + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I + sage: y in I # optional - sage.libs.pari True - sage: y/x in I + sage: y/x in I # optional - sage.libs.pari False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.pari True """ return self._structure[2](x) in self._module @@ -2736,11 +2736,11 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([1, y]) - sage: d = {I: 2} # indirect doctest + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari + sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari """ return hash((self._ring,self._module)) @@ -2754,11 +2754,11 @@ def __eq__(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([1, y]) - sage: I == I + I # indirect doctest + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari + sage: I == I + I # indirect doctest # optional - sage.libs.pari True """ if not isinstance(other, FunctionFieldIdeal_module): @@ -2782,21 +2782,21 @@ def module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: O = K.maximal_order(); O + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.maximal_order(); O # optional - sage.libs.pari Maximal order of Rational function field in x over Finite Field of size 7 - sage: K.polynomial_ring() + sage: K.polynomial_ring() # optional - sage.libs.pari Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7 - sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) - sage: I.gens() + sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x^2 + 1,) - sage: I.module() + sage: I.module() # optional - sage.libs.pari Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [x^2 + 1] - sage: V, from_V, to_V = K.vector_space(); V + sage: V, from_V, to_V = K.vector_space(); V # optional - sage.libs.pari Vector space of dimension 1 over Rational function field in x over Finite Field of size 7 - sage: I.module().is_submodule(V) + sage: I.module().is_submodule(V) # optional - sage.libs.pari True """ return self._module @@ -2814,10 +2814,10 @@ class FunctionFieldIdealInfinite_polymod(FunctionFieldIdealInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.ideal(1/y) + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(1/y) # optional - sage.libs.pari Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 """ @@ -2827,11 +2827,11 @@ def __init__(self, ring, ideal): TESTS:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: TestSuite(I).run() + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari """ FunctionFieldIdealInfinite.__init__(self, ring) self._ideal = ideal @@ -2842,17 +2842,17 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: d = { I: 1 } + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: d = { I: 1 } # optional - sage.libs.pari - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: d = { I: 1 } + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: d = { I: 1 } # optional - sage.libs.pari """ return hash((self.ring(), self._ideal)) @@ -2866,15 +2866,15 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y) - sage: 1/y in I + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: 1/y in I # optional - sage.libs.pari True - sage: 1/x in I + sage: 1/x in I # optional - sage.libs.pari False - sage: 1/x^2 in I + sage: 1/x^2 in I # optional - sage.libs.pari True """ F = self.ring().fraction_field() @@ -2891,21 +2891,21 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I + J + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I + J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2921,21 +2921,21 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I * J + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari Ideal (1/x^7*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I * J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari Ideal (1/x^4*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2947,11 +2947,11 @@ def __pow__(self, n): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: J = Oinf.ideal(1/x) - sage: J^3 + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: J^3 # optional - sage.libs.pari Ideal (1/x^3) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 """ @@ -2963,25 +2963,25 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: J = Oinf.ideal(y) - sage: ~J + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(y) # optional - sage.libs.pari + sage: ~J # optional - sage.libs.pari Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: J * ~J + sage: J * ~J # optional - sage.libs.pari Ideal (1) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: J = Oinf.ideal(y) - sage: ~J + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(y) # optional - sage.libs.pari + sage: ~J # optional - sage.libs.pari Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: J * ~J + sage: J * ~J # optional - sage.libs.pari Ideal (1) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2993,32 +2993,32 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I * J == J * I + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J == J * I # optional - sage.libs.pari True - sage: I + J == J + sage: I + J == J # optional - sage.libs.pari True - sage: I + J == I + sage: I + J == I # optional - sage.libs.pari False - sage: (I < J) == (not J < I) + sage: (I < J) == (not J < I) # optional - sage.libs.pari True - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x^2*1/y) - sage: J = Oinf.ideal(1/x) - sage: I * J == J * I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J == J * I # optional - sage.libs.pari True - sage: I + J == J + sage: I + J == J # optional - sage.libs.pari True - sage: I + J == I + sage: I + J == I # optional - sage.libs.pari False - sage: (I < J) == (not J < I) + sage: (I < J) == (not J < I) # optional - sage.libs.pari True """ return richcmp(self._ideal, other._ideal, op) @@ -3030,11 +3030,11 @@ def _relative_degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: [J._relative_degree for J,_ in I.factor()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: [J._relative_degree for J,_ in I.factor()] # optional - sage.libs.pari [1] """ if not self.is_prime(): @@ -3048,18 +3048,18 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(x+y) - sage: I.gens() + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x, y, 1/x^2*y^2) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(x+y) - sage: I.gens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari (x, y) """ F = self.ring().fraction_field() @@ -3072,18 +3072,18 @@ def gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(x+y) - sage: I.gens_two() + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_two() # optional - sage.libs.pari (x, y) - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2+Y+x+1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(x+y) - sage: I.gens_two() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2+Y+x+1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_two() # optional - sage.libs.pari (x,) """ F = self.ring().fraction_field() @@ -3096,11 +3096,11 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = K[] - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(x + y) - sage: I.gens_over_base() + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari (x, y, 1/x^2*y^2) """ F = self.ring().fraction_field() @@ -3113,11 +3113,11 @@ def ideal_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = K[] - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/y^2) - sage: I.ideal_below() + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y^2) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari Ideal (x^3) of Maximal order of Rational function field in x over Finite Field in z2 of size 3^2 """ @@ -3129,30 +3129,30 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 + t^2 - x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: I.is_prime() + sage: I.is_prime() # optional - sage.libs.pari False - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: I.is_prime() + sage: I.is_prime() # optional - sage.libs.pari False - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True """ return self._ideal.is_prime() @@ -3164,31 +3164,31 @@ def prime_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3+t^2-x^4) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True - sage: J.prime_below() + sage: J.prime_below() # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field in z2 of size 3^2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(1/x) - sage: I.factor() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] - sage: J.is_prime() + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari True - sage: J.prime_below() + sage: J.prime_below() # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -3209,11 +3209,11 @@ def valuation(self, ideal): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(y) - sage: [f.valuation(I) for f,_ in I.factor()] + sage: K.=FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(y) # optional - sage.libs.pari + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari [-1] """ if not self.is_prime(): @@ -3227,12 +3227,12 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: f= 1/x - sage: I = Oinf.ideal(f) - sage: I._factor() + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: f= 1/x # optional - sage.libs.pari + sage: I = Oinf.ideal(f) # optional - sage.libs.pari + sage: I._factor() # optional - sage.libs.pari [(Ideal (1/x, 1/x^4*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1), (Ideal (1/x, 1/x^2*y + 1) of Maximal infinite order of Function field in y @@ -3259,9 +3259,9 @@ class IdealMonoid(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid(); M + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid(); M # optional - sage.libs.pari Monoid of ideals of Maximal order of Rational function field in x over Finite Field of size 2 """ @@ -3271,10 +3271,10 @@ def __init__(self, R): TESTS:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid() - sage: TestSuite(M).run() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid() # optional - sage.libs.pari + sage: TestSuite(M).run() # optional - sage.libs.pari """ self.Element = R._ideal_class Parent.__init__(self, category = Monoids()) @@ -3288,9 +3288,9 @@ def _repr_(self): TESTS:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid(); M._repr_() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid(); M._repr_() # optional - sage.libs.pari 'Monoid of ideals of Maximal order of Rational function field in x over Finite Field of size 2' """ return "Monoid of ideals of %s" % self.__R @@ -3301,9 +3301,9 @@ def ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid(); M.ring() is O + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid(); M.ring() is O # optional - sage.libs.pari True """ return self.__R @@ -3314,12 +3314,12 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid() - sage: M(x) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid() # optional - sage.libs.pari + sage: M(x) # optional - sage.libs.pari Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 - sage: M([x-4, 1/x]) + sage: M([x-4, 1/x]) # optional - sage.libs.pari Ideal (1/x) of Maximal order of Rational function field in x over Finite Field of size 2 """ try: # x is an ideal @@ -3334,12 +3334,12 @@ def _coerce_map_from_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid() - sage: M.has_coerce_map_from(O) # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid() # optional - sage.libs.pari + sage: M.has_coerce_map_from(O) # indirect doctest # optional - sage.libs.pari True - sage: M.has_coerce_map_from(O.ideal_monoid()) + sage: M.has_coerce_map_from(O.ideal_monoid()) # optional - sage.libs.pari True """ if isinstance(x, IdealMonoid): @@ -3353,10 +3353,10 @@ def _an_element_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: O = K.maximal_order() - sage: M = O.ideal_monoid() - sage: M.an_element() # indirect doctest; random + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: M = O.ideal_monoid() # optional - sage.libs.pari + sage: M.an_element() # indirect doctest; random # optional - sage.libs.pari Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 """ diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index fbf3ef9e15d..265866eadaf 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -28,10 +28,10 @@ For global function fields, which have positive characteristics, the higher derivation is available:: - sage: K. = FunctionField(GF(2)); _.=K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: h = L.higher_derivation() - sage: h(y^2, 2) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h(y^2, 2) # optional - sage.libs.pari ((x^7 + 1)/x^2)*y^2 + x^3*y AUTHORS: @@ -391,24 +391,24 @@ def __init__(self, parent, u=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari This also works for iterated non-monic extensions:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - 1/x) - sage: R. = L[] - sage: M. = L.extension(z^2*y - x^3) - sage: M.derivation() + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari + sage: M.derivation() # optional - sage.libs.pari d/dz We can also create a multiple of the canonical derivation:: - sage: M.derivation([x]) + sage: M.derivation([x]) # optional - sage.libs.pari x*d/dz """ FunctionFieldDerivation.__init__(self, parent) @@ -434,15 +434,15 @@ def _call_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d(x) # indirect doctest + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d(x) # indirect doctest # optional - sage.libs.pari 0 - sage: d(y) + sage: d(y) # optional - sage.libs.pari 1 - sage: d(y^2) + sage: d(y^2) # optional - sage.libs.pari 0 """ @@ -457,13 +457,13 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: L. = K.extension(y^3 - x) - sage: d = L.derivation() - sage: d + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari d/dy - sage: d + d + sage: d + d # optional - sage.libs.pari 2*d/dy """ return type(self)(self.parent(), [self._u + other._u]) @@ -474,13 +474,13 @@ def _lmul_(self, factor): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari d/dy - sage: y * d + sage: y * d # optional - sage.libs.pari y*d/dy """ return type(self)(self.parent(), [factor * self._u]) @@ -496,8 +496,8 @@ class FunctionFieldHigherDerivation(Map): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: F.higher_derivation() + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.higher_derivation() # optional - sage.libs.pari Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 @@ -508,9 +508,9 @@ def __init__(self, field): TESTS:: - sage: F. = FunctionField(GF(4)) - sage: h = F.higher_derivation() - sage: TestSuite(h).run(skip='_test_category') + sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari """ Map.__init__(self, Hom(field, field, Sets())) self._field = field @@ -526,9 +526,9 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h # indirect doctest + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # indirect doctest # optional - sage.libs.pari Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 @@ -541,9 +541,9 @@ def __eq__(self, other) -> bool: TESTS:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: loads(dumps(h)) == h + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: loads(dumps(h)) == h # optional - sage.libs.pari True """ if isinstance(other, FunctionFieldHigherDerivation): @@ -559,9 +559,9 @@ def _pth_root_in_prime_field(e): sage: from sage.rings.function_field.maps import _pth_root_in_prime_field sage: p = 5 - sage: F. = GF(p) - sage: e = F.random_element() - sage: _pth_root_in_prime_field(e)^p == e + sage: F. = GF(p) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari True """ return e @@ -575,9 +575,9 @@ def _pth_root_in_finite_field(e): sage: from sage.rings.function_field.maps import _pth_root_in_finite_field sage: p = 3 - sage: F. = GF(p^2) - sage: e = F.random_element() - sage: _pth_root_in_finite_field(e)^p == e + sage: F. = GF(p^2) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari True """ return e.pth_root() @@ -593,13 +593,13 @@ class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 - sage: h(x^2,2) + sage: h(x^2,2) # optional - sage.libs.pari 1 """ def __init__(self, field): @@ -608,9 +608,9 @@ def __init__(self, field): TESTS:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: TestSuite(h).run(skip='_test_category') + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari """ FunctionFieldHigherDerivation.__init__(self, field) @@ -623,9 +623,9 @@ def _call_with_args(self, f, args=(), kwds={}): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h(x^2,2) # indirect doctest + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari 1 """ return self._derive(f, *args, **kwds) @@ -639,17 +639,17 @@ def _derive(self, f, i, separating_element=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h._derive(x^3,0) + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._derive(x^3,0) # optional - sage.libs.pari x^3 - sage: h._derive(x^3,1) + sage: h._derive(x^3,1) # optional - sage.libs.pari x^2 - sage: h._derive(x^3,2) + sage: h._derive(x^3,2) # optional - sage.libs.pari x - sage: h._derive(x^3,3) + sage: h._derive(x^3,3) # optional - sage.libs.pari 1 - sage: h._derive(x^3,4) + sage: h._derive(x^3,4) # optional - sage.libs.pari 0 """ F = self._field @@ -706,11 +706,11 @@ def _prime_power_representation(self, f, separating_element=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h._prime_power_representation(x^2 + x + 1) + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari [x + 1, 1] - sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x + sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari True """ F = self._field @@ -756,9 +756,9 @@ def _pth_root(self, c): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: h = F.higher_derivation() - sage: h._pth_root((x^2+1)^2) + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari x^2 + 1 """ K = self._field @@ -785,14 +785,14 @@ class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: h + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari, sage.modules Higher derivation map: From: Function field in y defined by y^3 + x^3*y + x To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) + sage: h(y^2, 2) # optional - sage.libs.pari, sage.modules ((x^7 + 1)/x^2)*y^2 + x^3*y """ @@ -802,10 +802,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: TestSuite(h).run(skip=['_test_category']) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari, sage.modules """ FunctionFieldHigherDerivation.__init__(self, field) @@ -828,10 +828,10 @@ def _call_with_args(self, f, args, kwds): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: h(y^2,2) # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari, sage.modules ((x^7 + 1)/x^2)*y^2 + x^3*y """ return self._derive(f, *args, **kwds) @@ -845,20 +845,20 @@ def _derive(self, f, i, separating_element=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: y^3 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: y^3 # optional - sage.libs.pari, sage.modules x^3*y + x - sage: h._derive(y^3,0) + sage: h._derive(y^3,0) # optional - sage.libs.pari, sage.modules x^3*y + x - sage: h._derive(y^3,1) + sage: h._derive(y^3,1) # optional - sage.libs.pari, sage.modules x^4*y^2 + 1 - sage: h._derive(y^3,2) + sage: h._derive(y^3,2) # optional - sage.libs.pari, sage.modules x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) + sage: h._derive(y^3,3) # optional - sage.libs.pari, sage.modules (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) + sage: h._derive(y^3,4) # optional - sage.libs.pari, sage.modules (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y """ F = self._field @@ -944,11 +944,11 @@ def _prime_power_representation(self, f, separating_element=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: b = h._prime_power_representation(y) - sage: y == b[0]^2 + b[1]^2 * x + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: b = h._prime_power_representation(y) # optional - sage.libs.pari, sage.modules + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari, sage.modules True """ F = self._field @@ -990,10 +990,10 @@ def _pth_root(self, c): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: h._pth_root((x^2 + y^2)^2) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari, sage.modules y^2 + x^2 """ K = self._field.base_field() # rational function field @@ -1245,7 +1245,7 @@ class MapVectorSpaceToFunctionField(FunctionFieldVectorSpaceIsomorphism): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); f + sage: V, f, t = L.vector_space(); f # optional - sage.modules Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 @@ -1256,7 +1256,7 @@ def __init__(self, V, K): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); type(f) + sage: V, f, t = L.vector_space(); type(f) # optional - sage.modules """ self._V = V @@ -1277,8 +1277,8 @@ def _call_(self, v): sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest + sage: V, f, t = L.vector_space() # optional - sage.modules + sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.modules 1/x^3*y + x TESTS: @@ -1287,7 +1287,7 @@ def _call_(self, v): sage: R. = L[] sage: M. = L.extension(z^3 - y - x) - sage: for F in [K,L,M]: + sage: for F in [K,L,M]: # optional - sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -1320,8 +1320,8 @@ def domain(self): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f.domain() + sage: V, f, t = L.vector_space() # optional - sage.modules + sage: f.domain() # optional - sage.modules Vector space of dimension 2 over Rational function field in x over Rational Field """ return self._V @@ -1334,8 +1334,8 @@ def codomain(self): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f.codomain() + sage: V, f, t = L.vector_space() # optional - sage.modules + sage: f.codomain() # optional - sage.modules Function field in y defined by y^2 - x*y + 4*x^3 """ return self._K @@ -1349,7 +1349,7 @@ class MapFunctionFieldToVectorSpace(FunctionFieldVectorSpaceIsomorphism): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); t + sage: V, f, t = L.vector_space(); t # optional - sage.modules Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -1368,8 +1368,8 @@ def __init__(self, K, V): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: TestSuite(t).run(skip="_test_category") + sage: V, f, t = L.vector_space() # optional - sage.modules + sage: TestSuite(t).run(skip="_test_category") # optional - sage.modules """ self._V = V self._K = K @@ -1385,8 +1385,8 @@ def _call_(self, x): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: t(x + (1/x^3)*y) # indirect doctest + sage: V, f, t = L.vector_space() # optional - sage.modules + sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.modules (x, 1/x^3) TESTS: @@ -1395,7 +1395,7 @@ def _call_(self, x): sage: R. = L[] sage: M. = L.extension(z^3 - y - x) - sage: for F in [K,L,M]: + sage: for F in [K,L,M]: # optional - sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -1448,10 +1448,10 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x) - sage: f = L.hom(y*2) - sage: f._repr_type() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = L.hom(y*2) # optional - sage.libs.pari + sage: f._repr_type() # optional - sage.libs.pari 'Function Field' """ return "Function Field" @@ -1462,10 +1462,10 @@ def _repr_defn(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x) - sage: f = L.hom(y*2) - sage: f._repr_defn() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = L.hom(y*2) # optional - sage.libs.pari + sage: f._repr_defn() # optional - sage.libs.pari 'y |--> 2*y' """ a = '%s |--> %s' % (self.domain().variable_name(), self._im_gen) @@ -1480,14 +1480,14 @@ class FunctionFieldMorphism_polymod(FunctionFieldMorphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x) - sage: f = L.hom(y*2); f + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = L.hom(y*2); f # optional - sage.libs.pari Function Field endomorphism of Function field in y defined by y^3 + 6*x^3 + x Defn: y |--> 2*y - sage: factor(L.polynomial()) + sage: factor(L.polynomial()) # optional - sage.libs.pari y^3 + 6*x^3 + x - sage: f(y).charpoly('y') + sage: f(y).charpoly('y') # optional - sage.libs.pari y^3 + 6*x^3 + x """ def __init__(self, parent, im_gen, base_morphism): @@ -1496,10 +1496,10 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x) - sage: f = L.hom(y*2) - sage: TestSuite(f).run(skip="_test_category") + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = L.hom(y*2) # optional - sage.libs.pari + sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -1515,11 +1515,11 @@ def _call_(self, x): """ EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) - sage: f(y/x + x^2/(x+1)) # indirect doctest + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari + sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari 2/x*y + x^2/(x + 1) - sage: f(y) + sage: f(y) # optional - sage.libs.pari 2*y """ v = x.list() @@ -1539,8 +1539,8 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: f = K.hom(1/x); f + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: f = K.hom(1/x); f # optional - sage.libs.pari Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> 1/x """ @@ -1550,27 +1550,27 @@ def _call_(self, x): """ EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: f = K.hom(1/x); f + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: f = K.hom(1/x); f # optional - sage.libs.pari Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> 1/x - sage: f(x+1) # indirect doctest + sage: f(x+1) # indirect doctest # optional - sage.libs.pari (x + 1)/x - sage: 1/x + 1 + sage: 1/x + 1 # optional - sage.libs.pari (x + 1)/x You can specify a morphism on the base ring:: - sage: Qi = GaussianIntegers().fraction_field() - sage: i = Qi.gen() - sage: K. = FunctionField(Qi) - sage: phi1 = Qi.hom([CC.gen()]) - sage: phi2 = Qi.hom([-CC.gen()]) - sage: f = K.hom(CC.pi(),phi1) - sage: f(1+i+x) + sage: Qi = GaussianIntegers().fraction_field() # optional - sage.rings.number_field + sage: i = Qi.gen() # optional - sage.rings.number_field + sage: K. = FunctionField(Qi) # optional - sage.rings.number_field + sage: phi1 = Qi.hom([CC.gen()]) # optional - sage.rings.number_field + sage: phi2 = Qi.hom([-CC.gen()]) # optional - sage.rings.number_field + sage: f = K.hom(CC.pi(), phi1) # optional - sage.rings.number_field + sage: f(1 + i + x) # optional - sage.rings.number_field 4.14159265358979 + 1.00000000000000*I - sage: g = K.hom(CC.pi(),phi2) - sage: g(1+i+x) + sage: g = K.hom(CC.pi(), phi2) # optional - sage.rings.number_field + sage: g(1 + i + x) # optional - sage.rings.number_field 4.14159265358979 - 1.00000000000000*I """ a = x.element() @@ -1774,35 +1774,35 @@ class FunctionFieldCompletion(Map): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m # optional - sage.libs.pari Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x) + sage: m(x) # optional - sage.libs.pari s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) - sage: m(y) + sage: m(y) # optional - sage.libs.pari s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) - sage: m(x*y) == m(x) * m(y) + sage: m(x*y) == m(x) * m(y) # optional - sage.libs.pari True - sage: m(x+y) == m(x) + m(y) + sage: m(x+y) == m(x) + m(y) # optional - sage.libs.pari True The variable name of the series can be supplied. If the place is not rational such that the residue field is a proper extension of the constant field, you can also specify the generator name of the extension:: - sage: p2 = L.places_finite(2)[0] - sage: p2 + sage: p2 = L.places_finite(2)[0] # optional - sage.libs.pari + sage: p2 # optional - sage.libs.pari Place (x^2 + x + 1, x*y + 1) - sage: m2 = L.completion(p2, 't', gen_name='b') - sage: m2(x) + sage: m2 = L.completion(p2, 't', gen_name='b') # optional - sage.libs.pari + sage: m2(x) # optional - sage.libs.pari (b + 1) + t + t^2 + t^4 + t^8 + t^16 + O(t^20) - sage: m2(y) + sage: m2(y) # optional - sage.libs.pari b + b*t + b*t^3 + b*t^4 + (b + 1)*t^5 + (b + 1)*t^7 + b*t^9 + b*t^11 + b*t^12 + b*t^13 + b*t^15 + b*t^16 + (b + 1)*t^17 + (b + 1)*t^19 + O(t^20) """ @@ -1812,11 +1812,11 @@ def __init__(self, field, place, name=None, prec=None, gen_name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m # optional - sage.libs.pari Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -1850,11 +1850,11 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m # indirect doctest # optional - sage.libs.pari Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -1867,11 +1867,11 @@ def _call_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m(y) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m(y) # optional - sage.libs.pari s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) """ if self._precision == infinity: @@ -1885,11 +1885,11 @@ def _call_with_args(self, f, args, kwds): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m(x+y, 10) # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m(x+y, 10) # indirect doctest # optional - sage.libs.pari s^-1 + 1 + s^2 + s^4 + s^8 + O(s^9) """ if self._precision == infinity: @@ -1909,11 +1909,11 @@ def _expand(self, f, prec=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m(x, prec=20) # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m(x, prec=20) # indirect doctest # optional - sage.libs.pari s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) """ @@ -1943,15 +1943,15 @@ def _expand_lazy(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p, prec=infinity) - sage: e = m(x); e + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p, prec=infinity) # optional - sage.libs.pari + sage: e = m(x); e # optional - sage.libs.pari s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + ... - sage: e.coefficient(99) # indirect doctest + sage: e.coefficient(99) # indirect doctest # optional - sage.libs.pari 0 - sage: e.coefficient(100) + sage: e.coefficient(100) # optional - sage.libs.pari 1 """ place = self._place @@ -1975,11 +1975,11 @@ def default_precision(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: m = L.completion(p) - sage: m.default_precision() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: m = L.completion(p) # optional - sage.libs.pari + sage: m.default_precision() # optional - sage.libs.pari 20 """ return self._precision @@ -1995,14 +1995,14 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: R = p.valuation_ring() - sage: k, fr_k, to_k = R.residue_field() - sage: k + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: R = p.valuation_ring() # optional - sage.libs.pari + sage: k, fr_k, to_k = R.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari Finite Field of size 2 - sage: fr_k + sage: fr_k # optional - sage.libs.pari Ring morphism: From: Finite Field of size 2 To: Valuation ring at Place (x, x*y) @@ -2023,13 +2023,13 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) - sage: F. = K.extension(t^2-x^3-1) - sage: O = F.maximal_order() - sage: I = O.ideal(x-2) - sage: D = I.divisor() - sage: V, from_V, to_V = D.function_space() - sage: from_V + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x-2) # optional - sage.libs.pari + sage: D = I.divisor() # optional - sage.libs.pari + sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari + sage: from_V # optional - sage.libs.pari Linear map: From: Vector space of dimension 2 over Finite Field of size 5 To: Function field in y defined by y^2 + 4*x^3 + 4 @@ -2050,13 +2050,13 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) - sage: F. = K.extension(t^2-x^3-1) - sage: O = F.maximal_order() - sage: I = O.ideal(x-2) - sage: D = I.divisor() - sage: V, from_V, to_V = D.function_space() - sage: to_V + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x-2) # optional - sage.libs.pari + sage: D = I.divisor() # optional - sage.libs.pari + sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari + sage: to_V # optional - sage.libs.pari Section of linear map: From: Function field in y defined by y^2 + 4*x^3 + 4 To: Vector space of dimension 2 over Finite Field of size 5 diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index d27d3c3b452..f6f458d9025 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -30,49 +30,49 @@ `O` and one maximal infinite order `O_\infty`. There are other non-maximal orders such as equation orders:: - sage: K. = FunctionField(GF(3)); R. = K[] - sage: L. = K.extension(y^3-y-x) - sage: O = L.equation_order() - sage: 1/y in O + sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - y - x) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: 1/y in O # optional - sage.libs.pari False - sage: x/y in O + sage: x/y in O # optional - sage.libs.pari True Sage provides an extensive functionality for computations in maximal orders of function fields. For example, you can decompose a prime ideal of a rational function field in an extension:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: o = K.maximal_order() - sage: p = o.ideal(x+1) - sage: p.is_prime() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: p = o.ideal(x+1) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: O.decomposition(p) + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O.decomposition(p) # optional - sage.libs.pari [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - sage: p1,relative_degree,ramification_index = O.decomposition(p)[1] - sage: p1.parent() + sage: p1, relative_degree,ramification_index = O.decomposition(p)[1] # optional - sage.libs.pari + sage: p1.parent() # optional - sage.libs.pari Monoid of ideals of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: relative_degree + sage: relative_degree # optional - sage.libs.pari 2 - sage: ramification_index + sage: ramification_index # optional - sage.libs.pari 1 When the base constant field is the algebraic field `\QQbar`, the only prime ideals of the maximal order of the rational function field are linear polynomials. :: - sage: K. = FunctionField(QQbar) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^3-x^2)) - sage: p = K.maximal_order().ideal(x) - sage: L.maximal_order().decomposition(p) + sage: K. = FunctionField(QQbar) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(y^2 - (x^3-x^2)) # optional - sage.rings.number_field + sage: p = K.maximal_order().ideal(x) # optional - sage.rings.number_field + sage: L.maximal_order().decomposition(p) # optional - sage.rings.number_field [(Ideal (1/x*y - I) of Maximal order of Function field in y defined by y^2 - x^3 + x^2, 1, 1), @@ -267,9 +267,9 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari Order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under @@ -304,10 +304,10 @@ def __init__(self, basis, check=True): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -382,35 +382,36 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal([y]); I + sage: I = O.ideal([y]); I # optional - sage.modules Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: I*I + sage: I*I # optional - sage.modules Ideal (y^2) of Maximal order of Rational function field in y over Rational Field We construct some ideals in a nontrivial function field:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() - Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 + sage: I.module() # optional - sage.libs.pari, sage.modules + Free module of degree 2 and rank 2 over + Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] [0 1] There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([y]); I + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I + sage: y in I # optional - sage.libs.pari, sage.modules True - sage: y^2 in I + sage: y^2 in I # optional - sage.libs.pari, sage.modules False """ F = self.function_field() @@ -436,23 +437,23 @@ def ideal(self, *gens): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: O.ideal(y) + sage: O.ideal(y) # optional - sage.modules Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list + sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list # optional - sage.modules True A fractional ideal of a nontrivial extension:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: O = K.maximal_order() - sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) - sage: S = L.equation_order() - sage: S.ideal(1/y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari, sage.modules + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: S = L.equation_order() # optional - sage.libs.pari + sage: S.ideal(1/y) # optional - sage.libs.pari, sage.modules Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 + sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari, sage.modules Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) + sage: I2 == S.ideal(I) # optional - sage.libs.pari, sage.modules True """ if len(gens) == 1: @@ -472,10 +473,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.polynomial() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.polynomial() # optional - sage.libs.pari y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -486,10 +487,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.basis() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.basis() # optional - sage.libs.pari, sage.modules (1, y, y^2, y^3) """ return self._basis @@ -501,10 +502,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.free_module() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.free_module() # optional - sage.libs.pari, sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -525,11 +526,11 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: f = (x + y)^3 - sage: O.coordinate_vector(f) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: f = (x + y)^3 # optional - sage.libs.pari, sage.modules + sage: O.coordinate_vector(f) # optional - sage.libs.pari, sage.modules (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e), check=False) @@ -563,16 +564,16 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order_infinite(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari, sage.modules Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under multiplication and contains the identity element (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari, sage.modules Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication @@ -581,7 +582,7 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari, sage.modules Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -589,9 +590,9 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): Note that 1 does not need to be an element of the basis, as long as it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O + sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari, sage.modules Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.pari, sage.modules (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) """ def __init__(self, basis, check=True): @@ -600,9 +601,9 @@ def __init__(self, basis, check=True): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order_infinite() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order_infinite() # optional - sage.libs.pari, sage.modules sage: TestSuite(O).run() """ if len(basis) == 0: @@ -693,13 +694,13 @@ def ideal_with_gens_over_base(self, gens): We construct some ideals in a nontrivial function field:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari, sage.modules Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() + sage: I.module() # optional - sage.libs.pari, sage.modules Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] @@ -707,14 +708,14 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([y]); I + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I + sage: y in I # optional - sage.libs.pari, sage.modules True - sage: y^2 in I + sage: y^2 in I # optional - sage.libs.pari, sage.modules False """ F = self.function_field() @@ -784,10 +785,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.basis() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.basis() # optional - sage.libs.pari, sage.modules (1, y, y^2, y^3) """ return self._basis @@ -799,10 +800,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.free_module() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.free_module() # optional - sage.libs.pari, sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -840,9 +841,9 @@ class FunctionFieldMaximalOrder_rational(FunctionFieldMaximalOrder): EXAMPLES:: - sage: K. = FunctionField(GF(19)); K + sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order(); R + sage: R = K.maximal_order(); R # optional - sage.libs.pari Maximal order of Rational function field in t over Finite Field of size 19 """ def __init__(self, field): @@ -903,7 +904,7 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x^3 - 1) sage: O = L.equation_order() - sage: O.ideal_with_gens_over_base([x^3+1,-y]) + sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ideal(gens) @@ -931,60 +932,60 @@ def _residue_field(self, ideal, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: I = O.ideal(x^2 + x + 1) - sage: R, fr_R, to_R = O._residue_field(I) - sage: R + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari Finite Field in z2 of size 2^2 - sage: [to_R(fr_R(e)) == e for e in R] + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari [True, True, True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari [True, True, True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari True - sage: to_R(e1).parent() is R + sage: to_R(e1).parent() is R # optional - sage.libs.pari True - sage: to_R(e2).parent() is R + sage: to_R(e2).parent() is R # optional - sage.libs.pari True - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: I = O.ideal(x + 1) - sage: R, fr_R, to_R = O._residue_field(I) - sage: R + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x + 1) # optional - sage.libs.pari + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari Finite Field of size 2 - sage: [to_R(fr_R(e)) == e for e in R] + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari [True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari [True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari True - sage: to_R(e1).parent() is R + sage: to_R(e1).parent() is R # optional - sage.libs.pari True - sage: to_R(e2).parent() is R + sage: to_R(e2).parent() is R # optional - sage.libs.pari True sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: I = O.ideal(x^2 + x + 1) - sage: R, fr_R, to_R = O._residue_field(I) - sage: R + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.rings.number_field + sage: R # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 + x + 1 - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.rings.number_field + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.rings.number_field True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.rings.number_field True - sage: to_R(e1).parent() is R + sage: to_R(e1).parent() is R # optional - sage.rings.number_field True - sage: to_R(e2).parent() is R + sage: to_R(e2).parent() is R # optional - sage.rings.number_field True sage: F. = FunctionField(QQ) @@ -1057,32 +1058,32 @@ def _residue_field_global(self, q, name=None): EXAMPLES:: - sage: k. = GF(4) - sage: F. = FunctionField(k) - sage: O = F.maximal_order() - sage: O._ring + sage: k. = GF(4) # optional - sage.libs.pari + sage: F. = FunctionField(k) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O._ring # optional - sage.libs.pari Univariate Polynomial Ring in x over Finite Field in a of size 2^2 - sage: f = x^3 + x + 1 - sage: _f = f.numerator() - sage: _f.is_irreducible() + sage: f = x^3 + x + 1 # optional - sage.libs.pari + sage: _f = f.numerator() # optional - sage.libs.pari + sage: _f.is_irreducible() # optional - sage.libs.pari True - sage: K, fr_K, to_K = O._residue_field_global(_f) - sage: K + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari, sage.modules + sage: K # optional - sage.libs.pari, sage.modules Finite Field in z6 of size 2^6 - sage: all(to_K(fr_K(e)) == e for e in K) + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari, sage.modules True - sage: k. = GF(2) - sage: F. = FunctionField(k) - sage: O = F.maximal_order() - sage: O._ring + sage: k. = GF(2) # optional - sage.libs.pari + sage: F. = FunctionField(k) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O._ring # optional - sage.libs.pari Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: f = x^3 + x + 1 - sage: _f = f.numerator() - sage: _f.is_irreducible() + sage: f = x^3 + x + 1 # optional - sage.libs.pari + sage: _f = f.numerator() # optional - sage.libs.pari + sage: _f.is_irreducible() # optional - sage.libs.pari True - sage: K, fr_K, to_K = O._residue_field_global(_f) - sage: all(to_K(fr_K(e)) == e for e in K) + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari, sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari, sage.modules True """ @@ -1143,9 +1144,9 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) - sage: O = K.maximal_order() - sage: O.basis() + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari (1,) """ return self._basis @@ -1232,10 +1233,10 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules """ FunctionFieldMaximalOrder.__init__(self, field, ideal_class) @@ -1325,26 +1326,26 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2-x*Y+x^2+1) - sage: O = L.maximal_order() - sage: y in O + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: y in O # optional - sage.libs.pari, sage.modules True - sage: 1/y in O + sage: 1/y in O # optional - sage.libs.pari, sage.modules False - sage: x in O + sage: x in O # optional - sage.libs.pari, sage.modules True - sage: 1/x in O + sage: 1/x in O # optional - sage.libs.pari, sage.modules False - sage: L.=K.extension(Y^2+Y+x+1/x) - sage: O = L.maximal_order() - sage: 1 in O + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: 1 in O # optional - sage.libs.pari, sage.modules True - sage: y in O + sage: y in O # optional - sage.libs.pari, sage.modules False - sage: x*y in O + sage: x*y in O # optional - sage.libs.pari, sage.modules True - sage: x^2*y in O + sage: x^2*y in O # optional - sage.libs.pari, sage.modules True """ F = self.function_field() @@ -1367,28 +1368,29 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order(); O # optional - sage.libs.pari, sage.modules Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() - Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 + sage: I.module() # optional - sage.libs.pari, sage.modules + Free module of degree 2 and rank 2 over + Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] [0 1] There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([y]); I + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I + sage: y in I # optional - sage.libs.pari, sage.modules True - sage: y^2 in I + sage: y^2 in I # optional - sage.libs.pari, sage.modules False """ return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) @@ -1404,16 +1406,16 @@ def _ideal_from_vectors(self, vecs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: v1 = O.coordinate_vector(x^3+1) - sage: v2 = O.coordinate_vector(y) - sage: v1 + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: v1 = O.coordinate_vector(x^3+1) # optional - sage.libs.pari, sage.modules + sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari, sage.modules + sage: v1 # optional - sage.libs.pari, sage.modules (x^3 + 1, 0) - sage: v2 + sage: v2 # optional - sage.libs.pari, sage.modules (0, 1) - sage: O._ideal_from_vectors([v1,v2]) + sage: O._ideal_from_vectors([v1,v2]) # optional - sage.libs.pari, sage.modules Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -1437,18 +1439,18 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y^2) - sage: m = I.basis_matrix() - sage: v1 = m[0] - sage: v2 = m[1] - sage: v1 + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: I = O.ideal(y^2) # optional - sage.libs.pari, sage.modules + sage: m = I.basis_matrix() # optional - sage.libs.pari, sage.modules + sage: v1 = m[0] # optional - sage.libs.pari, sage.modules + sage: v2 = m[1] # optional - sage.libs.pari, sage.modules + sage: v1 # optional - sage.libs.pari, sage.modules (x^3 + 1, 0) - sage: v2 + sage: v2 # optional - sage.libs.pari, sage.modules (0, x^3 + 1) - sage: O._ideal_from_vectors([v1,v2]) # indirect doctest + sage: O._ideal_from_vectors([v1,v2]) # indirect doctest # optional - sage.libs.pari, sage.modules Ideal (x^3 + 1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -1498,29 +1500,30 @@ def ideal(self, *gens, **kwargs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: O = K.maximal_order() - sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) - sage: S = L.maximal_order() - sage: S.ideal(1/y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: S = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: S.ideal(1/y) # optional - sage.libs.pari, sage.modules Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari, sage.modules Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) + sage: I2 == S.ideal(I) # optional - sage.libs.pari, sage.modules True sage: K. = FunctionField(QQ); R. = K[] sage: O = K.maximal_order() - sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) - sage: S = L.maximal_order() - sage: S.ideal(1/y) - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I2 = S.ideal(x^2-4); I2 + sage: I = O.ideal(x^2 - 4) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.modules + sage: S = L.maximal_order() # optional - sage.modules + sage: S.ideal(1/y) # optional - sage.modules + Ideal ((1/(x^3 + 1))*y) of + Maximal order of Function field in y defined by y^2 - x^3 - 1 + sage: I2 = S.ideal(x^2-4); I2 # optional - sage.modules Ideal (x^2 - 4) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I2 == S.ideal(I) + sage: I2 == S.ideal(I) # optional - sage.modules True """ if len(gens) == 1: @@ -1540,16 +1543,16 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.polynomial() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.polynomial() # optional - sage.libs.pari, sage.modules y^4 + x*y + 4*x + 1 sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.polynomial() + sage: O = L.equation_order() # optional - sage.modules + sage: O.polynomial() # optional - sage.modules y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -1561,17 +1564,17 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.basis() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules + sage: O.basis() # optional - sage.libs.pari, sage.modules (1, y, y^2, y^3) sage: K. = FunctionField(QQ) sage: R. = PolynomialRing(K) sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) - sage: O = F.maximal_order() - sage: O.basis() + sage: O = F.maximal_order() # optional - sage.modules + sage: O.basis() # optional - sage.modules (1, 1/x^4*y, 1/x^9*y^2, 1/x^13*y^3) """ return self._basis @@ -1584,16 +1587,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: O = L.maximal_order() - sage: O.gen() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O.gen() # optional - sage.libs.pari, sage.modules 1 - sage: O.gen(1) + sage: O.gen(1) # optional - sage.libs.pari, sage.modules y - sage: O.gen(2) + sage: O.gen(2) # optional - sage.libs.pari, sage.modules (1/(x^3 + x^2 + x))*y^2 - sage: O.gen(3) + sage: O.gen(3) # optional - sage.libs.pari, sage.modules Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -1609,10 +1612,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order() - sage: Oinf.ngens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: Oinf.ngens() # optional - sage.libs.pari, sage.modules 3 """ return len(self._basis) @@ -1623,10 +1626,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.free_module() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O.free_module() # optional - sage.libs.pari, sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 User basis matrix: [1 0 0 0] @@ -1642,19 +1645,19 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.coordinate_vector(y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O.coordinate_vector(y) # optional - sage.libs.pari, sage.modules (0, 1, 0, 0) - sage: O.coordinate_vector(x*y) + sage: O.coordinate_vector(x*y) # optional - sage.libs.pari, sage.modules (0, x, 0, 0) sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: f = (x + y)^3 - sage: O.coordinate_vector(f) + sage: O = L.equation_order() # optional - sage.modules + sage: f = (x + y)^3 # optional - sage.modules + sage: O.coordinate_vector(f) # optional - sage.modules (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e)) @@ -1670,12 +1673,12 @@ def _coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O._coordinate_vector(y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O._coordinate_vector(y) # optional - sage.libs.pari, sage.modules (0, 1, 0, 0) - sage: O._coordinate_vector(x*y) + sage: O._coordinate_vector(x*y) # optional - sage.libs.pari, sage.modules (0, x, 0, 0) """ v = self._module.coordinate_vector(self._to_module(e), check=False) @@ -1688,10 +1691,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.different() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O.different() # optional - sage.libs.pari, sage.modules Ideal (y^3 + 2*x) of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1704,10 +1707,10 @@ def codifferent(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.codifferent() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O.codifferent() # optional - sage.libs.pari, sage.modules Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y @@ -1724,10 +1727,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O._codifferent_matrix() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: O._codifferent_matrix() # optional - sage.libs.pari, sage.modules [ 4 0 0 4*x] [ 0 0 4*x 5*x + 3] [ 0 4*x 5*x + 3 0] @@ -1753,12 +1756,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x+1) - sage: O.decomposition(p) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules + sage: O.decomposition(p) # optional - sage.libs.pari, sage.modules [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -1877,9 +1880,9 @@ class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: L.maximal_order() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: L.maximal_order() # optional - sage.libs.pari, sage.modules Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1889,10 +1892,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules """ FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) @@ -1910,12 +1913,12 @@ def p_radical(self, prime): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x+1) - sage: O.p_radical(p) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules + sage: O.p_radical(p) # optional - sage.libs.pari, sage.modules Ideal (x + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -1969,12 +1972,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x+1) - sage: O.decomposition(p) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules + sage: O.decomposition(p) # optional - sage.libs.pari, sage.modules [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -2223,9 +2226,9 @@ def _repr_(self): sage: FunctionField(QQ,'y').maximal_order_infinite() Maximal infinite order of Rational function field in y over Rational Field - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: F.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return "Maximal infinite order of %s"%(self.function_field(),) @@ -2241,9 +2244,9 @@ class FunctionFieldMaximalOrderInfinite_rational(FunctionFieldMaximalOrderInfini EXAMPLES:: - sage: K. = FunctionField(GF(19)); K + sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order_infinite(); R + sage: R = K.maximal_order_infinite(); R # optional - sage.libs.pari Maximal infinite order of Rational function field in t over Finite Field of size 19 """ def __init__(self, field, category=None): @@ -2252,9 +2255,9 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(19)) - sage: O = K.maximal_order_infinite() - sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order_infinite() # optional - sage.libs.pari + sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') # optional - sage.libs.pari """ FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_rational, category=PrincipalIdealDomains().or_subcategory(category)) @@ -2292,9 +2295,9 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) - sage: O = K.maximal_order() - sage: O.basis() + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari (1,) """ return 1/self.function_field().gen() @@ -2334,9 +2337,9 @@ def prime_ideal(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) - sage: O = K.maximal_order_infinite() - sage: O.prime_ideal() + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order_infinite() # optional - sage.libs.pari + sage: O.prime_ideal() # optional - sage.libs.pari Ideal (1/t) of Maximal infinite order of Rational function field in t over Finite Field of size 19 """ @@ -2393,14 +2396,14 @@ class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinit EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: F.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: L.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ def __init__(self, field, category=None): @@ -2409,10 +2412,10 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order_infinite() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules """ FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) @@ -2433,18 +2436,18 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.basis() # optional - sage.libs.pari, sage.modules (1, 1/x*y) - sage: 1 in Oinf + sage: 1 in Oinf # optional - sage.libs.pari, sage.modules True - sage: 1/x*y in Oinf + sage: 1/x*y in Oinf # optional - sage.libs.pari, sage.modules True - sage: x*y in Oinf + sage: x*y in Oinf # optional - sage.libs.pari, sage.modules False - sage: 1/x in Oinf + sage: 1/x in Oinf # optional - sage.libs.pari, sage.modules True """ F = self.function_field() @@ -2468,18 +2471,18 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.basis() # optional - sage.libs.pari, sage.modules (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.basis() # optional - sage.libs.pari, sage.modules (1, 1/x*y) """ return self._basis @@ -2492,16 +2495,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.gen() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.gen() # optional - sage.libs.pari, sage.modules 1 - sage: Oinf.gen(1) + sage: Oinf.gen(1) # optional - sage.libs.pari, sage.modules 1/x^2*y - sage: Oinf.gen(2) + sage: Oinf.gen(2) # optional - sage.libs.pari, sage.modules (1/(x^4 + x^3 + x^2))*y^2 - sage: Oinf.gen(3) + sage: Oinf.gen(3) # optional - sage.libs.pari, sage.modules Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -2517,10 +2520,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.ngens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.ngens() # optional - sage.libs.pari, sage.modules 3 """ return len(self._basis) @@ -2535,19 +2538,19 @@ def ideal(self, *gens): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(x,y); I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari, sage.modules Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(x,y); I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari, sage.modules Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ if len(gens) == 1: @@ -2567,10 +2570,10 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) # optional - sage.libs.pari, sage.modules Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -2632,11 +2635,11 @@ def _to_iF(self, I): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(y) - sage: Oinf._to_iF(I) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: I = Oinf.ideal(y) # optional - sage.libs.pari, sage.modules + sage: Oinf._to_iF(I) # optional - sage.libs.pari, sage.modules Ideal (1, 1/x*s) of Maximal order of Function field in s defined by s^2 + x*s + x^3 + x """ @@ -2653,10 +2656,10 @@ def decomposition(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.decomposition() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.decomposition() # optional - sage.libs.pari, sage.modules [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -2664,10 +2667,10 @@ def decomposition(self): :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.decomposition() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.decomposition() # optional - sage.libs.pari, sage.modules [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] @@ -2675,8 +2678,8 @@ def decomposition(self): sage: K. = FunctionField(QQ); _. = K[] sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.decomposition() + sage: Oinf = F.maximal_order_infinite() # optional - sage.modules + sage: Oinf.decomposition() # optional - sage.modules [(Ideal (1/x^2*y - 1) of Maximal infinite order of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -2686,8 +2689,8 @@ def decomposition(self): sage: K. = FunctionField(QQ); _. = K[] sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.decomposition() + sage: Oinf = L.maximal_order_infinite() # optional - sage.modules + sage: Oinf.decomposition() # optional - sage.modules [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] """ @@ -2711,10 +2714,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.different() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf.different() # optional - sage.libs.pari, sage.modules Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2732,10 +2735,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf._codifferent_matrix() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: Oinf._codifferent_matrix() # optional - sage.libs.pari, sage.modules [ 0 1/x] [ 1/x 1/x^2] """ @@ -2761,13 +2764,13 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: f = 1/y^2 - sage: f in Oinf + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: f = 1/y^2 # optional - sage.libs.pari, sage.modules + sage: f in Oinf # optional - sage.libs.pari, sage.modules True - sage: Oinf.coordinate_vector(f) + sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari, sage.modules ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) """ return self._module.coordinate_vector(self._to_module(e)) diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 69993a4b744..88b93556232 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -11,9 +11,9 @@ All rational places of a function field can be computed:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: L.places() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: L.places() # optional - sage.libs.pari [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y)] @@ -21,20 +21,20 @@ The residue field associated with a place is given as an extension of the constant field:: - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: p = O.ideal(x^2 + x + 1).place() - sage: k, fr_k, to_k = p.residue_field() - sage: k + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari + sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari Finite Field in z2 of size 2^2 The homomorphisms are between the valuation ring and the residue field:: - sage: fr_k + sage: fr_k # optional - sage.libs.pari Ring morphism: From: Finite Field in z2 of size 2^2 To: Valuation ring at Place (x^2 + x + 1) - sage: to_k + sage: to_k # optional - sage.libs.pari Ring morphism: From: Valuation ring at Place (x^2 + x + 1) To: Finite Field in z2 of size 2^2 @@ -87,9 +87,9 @@ class FunctionFieldPlace(Element): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^3 + x + x^3*Y) - sage: L.places_finite()[0] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: L.places_finite()[0] # optional - sage.libs.pari Place (x, y) """ def __init__(self, parent, prime): @@ -98,10 +98,10 @@ def __init__(self, parent, prime): TESTS:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^3 + x + x^3*Y) - sage: p = L.places_finite()[0] - sage: TestSuite(p).run() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: TestSuite(p).run() # optional - sage.libs.pari """ Element.__init__(self, parent) @@ -113,10 +113,10 @@ def __hash__(self): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] - sage: L.=K.extension(Y^3 + x + x^3*Y) - sage: p = L.places_finite()[0] - sage: {p: 1} + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: {p: 1} # optional - sage.libs.pari {Place (x, y): 1} """ return hash((self.function_field(), self._prime)) @@ -127,10 +127,10 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p = L.places_finite()[0] - sage: p + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: p # optional - sage.libs.pari Place (x, y) """ try: @@ -146,10 +146,10 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3+x+x^3*Y) - sage: p = L.places_finite()[0] - sage: latex(p) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: latex(p) # optional - sage.libs.pari \left(y\right) """ return self._prime._latex_() @@ -160,14 +160,14 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: p1, p2, p3 = L.places()[:3] - sage: p1 < p2 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari + sage: p1 < p2 # optional - sage.libs.pari True - sage: p2 < p1 + sage: p2 < p1 # optional - sage.libs.pari False - sage: p1 == p3 + sage: p1 == p3 # optional - sage.libs.pari False """ from sage.rings.function_field.order import FunctionFieldOrderInfinite @@ -186,12 +186,12 @@ def _acted_upon_(self, other, self_on_left): EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) - sage: F. = K.extension(Y^2 - x^3 - 1) - sage: O = F.maximal_order() - sage: I = O.ideal(x + 1,y) - sage: P = I.place() - sage: -3*P + 5*P + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari + sage: P = I.place() # optional - sage.libs.pari + sage: -3*P + 5*P # optional - sage.libs.pari 2*Place (x + 1, y) """ if self_on_left: @@ -204,10 +204,10 @@ def _neg_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p1, p2, p3 = L.places()[:3] - sage: -p1 + p2 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari + sage: -p1 + p2 # optional - sage.libs.pari - Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -220,10 +220,10 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p1, p2, p3 = L.places()[:3] - sage: p1 + p2 + p3 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari + sage: p1 + p2 + p3 # optional - sage.libs.pari Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) + Place (x, y) @@ -237,10 +237,10 @@ def _sub_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p1, p2 = L.places()[:2] - sage: p1 - p2 + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p1, p2 = L.places()[:2] # optional - sage.libs.pari + sage: p1 - p2 # optional - sage.libs.pari Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -256,14 +256,14 @@ def __radd__(self, other): EXAMPLES:: - sage: k. = GF(2) - sage: K. = FunctionField(k) - sage: sum(K.places_finite()) + sage: k. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(k) # optional - sage.libs.pari + sage: sum(K.places_finite()) # optional - sage.libs.pari Place (x) + Place (x + 1) Note that this does not work, as wanted:: - sage: 0 + K.place_infinite() + sage: 0 + K.place_infinite() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: ... @@ -282,10 +282,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p = L.places()[0] - sage: p.function_field() == L + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p = L.places()[0] # optional - sage.libs.pari + sage: p.function_field() == L # optional - sage.libs.pari True """ return self.parent()._field @@ -296,10 +296,10 @@ def prime_ideal(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: p = L.places()[0] - sage: p.prime_ideal() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: p = L.places()[0] # optional - sage.libs.pari + sage: p.prime_ideal() # optional - sage.libs.pari Ideal (1/x^3*y^2 + 1/x) of Maximal infinite order of Function field in y defined by y^3 + x^3*y + x """ @@ -311,12 +311,12 @@ def divisor(self, multiplicity=1): EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) - sage: F. = K.extension(Y^2 - x^3 - 1) - sage: O = F.maximal_order() - sage: I = O.ideal(x + 1,y) - sage: P = I.place() - sage: P.divisor() + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x + 1,y) # optional - sage.libs.pari + sage: P = I.place() # optional - sage.libs.pari + sage: P.divisor() # optional - sage.libs.pari Place (x + 1, y) """ from .divisor import prime_divisor @@ -333,11 +333,11 @@ def degree(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: i = O.ideal(x^2 + x + 1) - sage: p = i.place() - sage: p.degree() + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: p = i.place() # optional - sage.libs.pari + sage: p.degree() # optional - sage.libs.pari 2 """ if self.is_infinite_place(): @@ -351,10 +351,10 @@ def is_infinite_place(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: F.places() + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari [Place (1/x), Place (x), Place (x + 1)] - sage: [p.is_infinite_place() for p in F.places()] + sage: [p.is_infinite_place() for p in F.places()] # optional - sage.libs.pari [True, False, False] """ F = self.function_field() @@ -366,10 +366,10 @@ def local_uniformizer(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: F.places() + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari [Place (1/x), Place (x), Place (x + 1)] - sage: [p.local_uniformizer() for p in F.places()] + sage: [p.local_uniformizer() for p in F.places()] # optional - sage.libs.pari [1/x, x, x + 1] """ return self.prime_ideal().gen() @@ -380,17 +380,17 @@ def residue_field(self, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: p = O.ideal(x^2 + x + 1).place() - sage: k, fr_k, to_k = p.residue_field() - sage: k + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari + sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari Finite Field in z2 of size 2^2 - sage: fr_k + sage: fr_k # optional - sage.libs.pari Ring morphism: From: Finite Field in z2 of size 2^2 To: Valuation ring at Place (x^2 + x + 1) - sage: to_k + sage: to_k # optional - sage.libs.pari Ring morphism: From: Valuation ring at Place (x^2 + x + 1) To: Finite Field in z2 of size 2^2 @@ -408,16 +408,16 @@ def _residue_field(self, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) - sage: O = F.maximal_order() - sage: i = O.ideal(x^2 + x + 1) - sage: p = i.place() - sage: R, fr, to = p._residue_field() - sage: R + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: p = i.place() # optional - sage.libs.pari + sage: R, fr, to = p._residue_field() # optional - sage.libs.pari + sage: R # optional - sage.libs.pari Finite Field in z2 of size 2^2 - sage: [fr(e) for e in R.list()] + sage: [fr(e) for e in R.list()] # optional - sage.libs.pari [0, x, x + 1, 1] - sage: to(x*(x+1)) == to(x) * to(x+1) + sage: to(x*(x+1)) == to(x) * to(x+1) # optional - sage.libs.pari True """ F = self.function_field() @@ -474,10 +474,10 @@ def valuation_ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: p.valuation_ring() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: p.valuation_ring() # optional - sage.libs.pari Valuation ring at Place (x, x*y) """ from .valuation_ring import FunctionFieldValuationRing @@ -495,14 +495,14 @@ def place_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: OK = K.maximal_order() - sage: OL = L.maximal_order() - sage: p = OK.ideal(x^2 + x + 1) - sage: dec = OL.decomposition(p) - sage: q = dec[0][0].place() - sage: q.place_below() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.place_below() # optional - sage.libs.pari Place (x^2 + x + 1) """ return self.prime_ideal().prime_below().place() @@ -513,14 +513,14 @@ def relative_degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: OK = K.maximal_order() - sage: OL = L.maximal_order() - sage: p = OK.ideal(x^2 + x + 1) - sage: dec = OL.decomposition(p) - sage: q = dec[0][0].place() - sage: q.relative_degree() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.relative_degree() # optional - sage.libs.pari 1 """ return self._prime._relative_degree @@ -531,14 +531,14 @@ def degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: OK = K.maximal_order() - sage: OL = L.maximal_order() - sage: p = OK.ideal(x^2 + x + 1) - sage: dec = OL.decomposition(p) - sage: q = dec[0][0].place() - sage: q.degree() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.degree() # optional - sage.libs.pari 2 """ return self.relative_degree() * self.place_below().degree() @@ -550,12 +550,12 @@ def is_infinite_place(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: pls = L.places() - sage: [p.is_infinite_place() for p in pls] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: pls = L.places() # optional - sage.libs.pari + sage: [p.is_infinite_place() for p in pls] # optional - sage.libs.pari [True, True, False] - sage: [p.place_below() for p in pls] + sage: [p.place_below() for p in pls] # optional - sage.libs.pari [Place (1/x), Place (1/x), Place (x)] """ return self.place_below().is_infinite_place() @@ -567,10 +567,10 @@ def local_uniformizer(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: pls = L.places() - sage: [p.local_uniformizer().valuation(p) for p in pls] + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: pls = L.places() # optional - sage.libs.pari + sage: [p.local_uniformizer().valuation(p) for p in pls] # optional - sage.libs.pari [1, 1, 1, 1, 1] """ gens = self._prime.gens() @@ -585,16 +585,16 @@ def gaps(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: O = L.maximal_order() - sage: p = O.ideal(x,y).place() - sage: p.gaps() # a Weierstrass place + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p.gaps() # a Weierstrass place # optional - sage.libs.pari [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3 * Y + x) - sage: [p.gaps() for p in L.places()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: [p.gaps() for p in L.places()] # optional - sage.libs.pari [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ if self.degree() == 1: @@ -612,16 +612,16 @@ def _gaps_rational(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: O = L.maximal_order() - sage: p = O.ideal(x,y).place() - sage: p.gaps() # indirect doctest + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p.gaps() # indirect doctest # optional - sage.libs.pari [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: [p.gaps() for p in L.places()] # indirect doctest + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.libs.pari [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ F = self.function_field() @@ -741,16 +741,16 @@ def _gaps_wronskian(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: O = L.maximal_order() - sage: p = O.ideal(x,y).place() - sage: p._gaps_wronskian() # a Weierstrass place + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3 * Y + x) - sage: [p._gaps_wronskian() for p in L.places()] + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.libs.pari [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ F = self.function_field() @@ -801,28 +801,28 @@ def residue_field(self, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: k, fr_k, to_k = p.residue_field() - sage: k + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari Finite Field of size 2 - sage: fr_k + sage: fr_k # optional - sage.libs.pari Ring morphism: From: Finite Field of size 2 To: Valuation ring at Place (x, x*y) - sage: to_k + sage: to_k # optional - sage.libs.pari Ring morphism: From: Valuation ring at Place (x, x*y) To: Finite Field of size 2 - sage: to_k(y) + sage: to_k(y) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: y fails to convert into the map's domain Valuation ring at Place (x, x*y)... - sage: to_k(1/y) + sage: to_k(1/y) # optional - sage.libs.pari 0 - sage: to_k(y/(1+y)) + sage: to_k(y/(1+y)) # optional - sage.libs.pari 1 """ return self.valuation_ring().residue_field(name=name) @@ -840,21 +840,21 @@ def _residue_field(self, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: k,fr_k,to_k = p._residue_field() - sage: k + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: k,fr_k,to_k = p._residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari Finite Field of size 2 - sage: [fr_k(e) for e in k] + sage: [fr_k(e) for e in k] # optional - sage.libs.pari [0, 1] :: - sage: K. = FunctionField(GF(9)); _. = K[] - sage: L. = K.extension(Y^3 + Y - x^4) - sage: p = L.places()[-1] - sage: p.residue_field() + sage: K. = FunctionField(GF(9)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.pari + sage: p = L.places()[-1] # optional - sage.libs.pari + sage: p.residue_field() # optional - sage.libs.pari (Finite Field in z2 of size 3^2, Ring morphism: From: Finite Field in z2 of size 3^2 To: Valuation ring at Place (x + 1, y + 2*z2), Ring morphism: @@ -885,11 +885,11 @@ def _residue_field(self, name=None): :: - sage: K. = FunctionField(QQbar); _. = K[] - sage: L. = K.extension(Y^3 + Y - x^4) - sage: O = K.maximal_order() - sage: I = O.ideal(x) - sage: [p.residue_field() for p in L.places_above(I.place())] + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: I = O.ideal(x) # optional - sage.rings.number_field + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.rings.number_field [(Algebraic Field, Ring morphism: From: Algebraic Field To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: @@ -1131,9 +1131,9 @@ class PlaceSet(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: L.place_set() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: L.place_set() # optional - sage.libs.pari Set of places of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldPlace @@ -1144,10 +1144,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: places = L.place_set() - sage: TestSuite(places).run() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: places = L.place_set() # optional - sage.libs.pari + sage: TestSuite(places).run() # optional - sage.libs.pari """ self.Element = field._place_class Parent.__init__(self, category = Sets().Infinite()) @@ -1160,9 +1160,9 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: L.place_set() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: L.place_set() # optional - sage.libs.pari Set of places of Function field in y defined by y^3 + x^3*y + x """ return "Set of places of {}".format(self._field) @@ -1173,11 +1173,11 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: places = L.place_set() - sage: O = L.maximal_order() - sage: places(O.ideal(x,y)) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: places = L.place_set() # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: places(O.ideal(x,y)) # optional - sage.libs.pari Place (x, y) """ from .ideal import FunctionFieldIdeal @@ -1193,10 +1193,10 @@ def _an_element_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: places = L.place_set() - sage: places.an_element() # random + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: places = L.place_set() # optional - sage.libs.pari + sage: places.an_element() # random # optional - sage.libs.pari Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 """ @@ -1216,10 +1216,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^3 + x^3*Y + x) - sage: PS = L.place_set() - sage: PS.function_field() == L + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: PS = L.place_set() # optional - sage.libs.pari + sage: PS.function_field() == L # optional - sage.libs.pari True """ return self._field diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index bb3a39c687a..3e30a43248a 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari r""" Valuation rings of function fields From deffc68ba392e6fcd29c33f400b9f93da54cbc9e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Mar 2023 23:16:44 -0800 Subject: [PATCH 10/54] sage.rings.function_field: Move some imports into methods --- .../rings/function_field/function_field.py | 8 ++--- src/sage/rings/function_field/ideal.py | 13 +++++---- src/sage/rings/function_field/maps.py | 18 +++++------- src/sage/rings/function_field/order.py | 29 ++++++++++++++----- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 22c342946f3..dbbf63c85dd 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -223,8 +223,6 @@ # **************************************************************************** from sage.misc.cachefunc import cached_method -from sage.interfaces.singular import singular - from sage.arith.functions import lcm from sage.rings.integer import Integer @@ -232,8 +230,6 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.qqbar_decorators import handle_AA_and_QQbar -from sage.modules.free_module_element import vector - from sage.categories.homset import Hom from sage.categories.function_fields import FunctionFields from sage.structure.category_object import CategoryObject @@ -2179,7 +2175,8 @@ def genus(self): # transcendental degree 1 over a rational function field of one variable if (isinstance(self._base_field, RationalFunctionField) and - self._base_field.constant_field().is_prime_field()): + self._base_field.constant_field().is_prime_field()): + from sage.interfaces.singular import singular # making the auxiliary ring which only has polynomials # with integral coefficients. @@ -3364,6 +3361,7 @@ def _weierstrass_places(self): This method implements Algorithm 30 in [Hes2002b]_. """ from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector W = self(self.base_field().gen()).differential().divisor() basis = W._basis() diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index a9a574bed90..cc2de46dad2 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -101,19 +101,13 @@ from sage.arith.power import generic_power -from sage.modules.free_module_element import vector - from sage.categories.monoids import Monoids from sage.rings.infinity import infinity from sage.rings.ideal import Ideal_generic -from sage.matrix.constructor import matrix - from .divisor import divisor -from .hermite_form_polynomial import reversed_hermite_form - class FunctionFieldIdeal(Element): """ @@ -1347,6 +1341,8 @@ def __contains__(self, x): sage: y^2 - 2 in I False """ + from sage.modules.free_module_element import vector + vec = self.ring().coordinate_vector(self._denominator * x) v = [] for e in vec: @@ -1559,6 +1555,8 @@ def _acted_upon_(self, other, on_left): sage: x * I == I * J # optional - sage.libs.pari True """ + from sage.modules.free_module_element import vector + O = self._ring mul = O._mul_vecs @@ -1592,6 +1590,7 @@ def intersect(self, other): """ from sage.matrix.special import block_matrix + from .hermite_form_polynomial import reversed_hermite_form A = self._hnf B = other._hnf @@ -2013,6 +2012,8 @@ def valuation(self, ideal): The method closely follows Algorithm 4.8.17 of [Coh1993]_. """ + from sage.matrix.constructor import matrix + if ideal.is_zero(): return infinity diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 265866eadaf..2e6c7cd0002 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -54,20 +54,14 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.categories.morphism import Morphism, SetMorphism -from sage.categories.map import Map +from sage.arith.misc import binomial from sage.categories.homset import Hom +from sage.categories.map import Map +from sage.categories.morphism import Morphism, SetMorphism from sage.categories.sets_cat import Sets - +from sage.rings.derivation import RingDerivationWithoutTwist from sage.rings.infinity import infinity from sage.rings.morphism import RingHomomorphism -from sage.rings.derivation import RingDerivationWithoutTwist - -from sage.modules.free_module_element import vector - -from sage.functions.other import binomial - -from sage.matrix.constructor import matrix class FunctionFieldDerivation(RingDerivationWithoutTwist): @@ -807,6 +801,8 @@ def __init__(self, field): sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari, sage.modules """ + from sage.matrix.constructor import matrix + FunctionFieldHigherDerivation.__init__(self, field) self._p = field.characteristic() @@ -996,6 +992,8 @@ def _pth_root(self, c): sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari, sage.modules y^2 + x^2 """ + from sage.modules.free_module_element import vector + K = self._field.base_field() # rational function field p = self._p diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index f6f458d9025..6d451781142 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -105,17 +105,17 @@ # https://www.gnu.org/licenses/ #***************************************************************************** +import sage.rings.abc + from sage.misc.cachefunc import cached_method from sage.modules.free_module_element import vector from sage.arith.functions import lcm from sage.arith.misc import GCD as gcd +from sage.rings.number_field.number_field_base import NumberField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.algebras.all import FiniteDimensionalAlgebra -from sage.rings.qqbar import QQbar -from sage.rings.number_field.number_field_base import NumberField from sage.structure.parent import Parent from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation @@ -124,8 +124,6 @@ from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.categories.euclidean_domains import EuclideanDomains -from sage.matrix.special import block_matrix -from sage.matrix.constructor import matrix from .ideal import ( IdealMonoid, @@ -1011,7 +1009,7 @@ def _residue_field(self, ideal, name=None): if F.is_global(): R, _from_R, _to_R = self._residue_field_global(q, name=name) - elif isinstance(K, NumberField) or K is QQbar: + elif isinstance(K, (NumberField, sage.rings.abc.AlgebraicField)): if name is None: name = 'a' if q.degree() == 1: @@ -1454,6 +1452,8 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): Ideal (x^3 + 1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ + from sage.matrix.constructor import matrix + R = self._module_base_ring._ring d = R(d) # make it sure that d is in the polynomial ring @@ -1736,6 +1736,8 @@ def _codifferent_matrix(self): [ 0 4*x 5*x + 3 0] [ 4*x 5*x + 3 0 3*x^2] """ + from sage.matrix.constructor import matrix + rows = [] for u in self.basis(): row = [] @@ -1785,6 +1787,9 @@ def decomposition(self, ideal): done in :meth:`FunctionFieldMaximalOrder_global.decomposition()` """ + from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra + from sage.matrix.constructor import matrix + F = self.function_field() n = F.degree() @@ -1922,6 +1927,8 @@ def p_radical(self, prime): Ideal (x + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ + from sage.matrix.constructor import matrix + g = prime.gens()[0] if not (g.denominator() == 1 and g.numerator().is_irreducible()): @@ -1947,7 +1954,7 @@ def p_radical(self, prime): for g in self.basis(): v = [to_Fp(c) for c in self._coordinate_vector(g**exp)] mat.append(v) - mat = matrix(Fp,mat) + mat = matrix(Fp, mat) ker = mat.kernel() # construct module generators of the p-radical @@ -1983,6 +1990,8 @@ def decomposition(self, ideal): (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] """ + from sage.matrix.constructor import matrix + F = self.function_field() n = F.degree() @@ -2050,6 +2059,8 @@ def decomposition(self, ideal): ############################# # Buchman-Lenstra algorithm # ############################# + from sage.matrix.special import block_matrix + pO = self.ideal(p) Ip = self.p_radical(ideal) Ob = matrix.identity(Fp, n) @@ -2592,6 +2603,8 @@ def ideal_with_gens_over_base(self, gens): # if n is large enough, and then J_n is the I with the spurious # factors removed. For a fractional ideal, we also need to find # the largest factor x^m that divides the denominator. + from sage.matrix.special import block_matrix + d = ideal.denominator() h = ideal.hnf() x = d.parent().gen() @@ -2742,6 +2755,8 @@ def _codifferent_matrix(self): [ 0 1/x] [ 1/x 1/x^2] """ + from sage.matrix.constructor import matrix + rows = [] for u in self.basis(): row = [] From 933858480697a86398871d0f54265e277f5d1c19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Mar 2023 21:09:53 -0800 Subject: [PATCH 11/54] sage.rings.function_field.derivations: Split out from .maps --- src/sage/rings/derivation.py | 6 +- src/sage/rings/function_field/derivations.py | 1084 +++++++++++++++++ .../rings/function_field/function_field.py | 22 +- src/sage/rings/function_field/maps.py | 1077 +--------------- 4 files changed, 1108 insertions(+), 1081 deletions(-) create mode 100644 src/sage/rings/function_field/derivations.py diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 29f3a18d662..c2ef53ebba1 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -391,13 +391,13 @@ def __init__(self, domain, codomain, twist=None): constants, sharp = self._base_derivation._constants self._constants = (constants, False) # can we do better? elif isinstance(domain, RationalFunctionField): - from sage.rings.function_field.maps import FunctionFieldDerivation_rational + from sage.rings.function_field.derivations import FunctionFieldDerivation_rational self.Element = FunctionFieldDerivation_rational self._gens = self._basis = [ None ] self._dual_basis = [ domain.gen() ] elif isinstance(domain, FunctionField): if domain.is_separable(): - from sage.rings.function_field.maps import FunctionFieldDerivation_separable + from sage.rings.function_field.derivations import FunctionFieldDerivation_separable self._base_derivation = RingDerivationModule(domain.base_ring(), defining_morphism) self.Element = FunctionFieldDerivation_separable try: @@ -410,7 +410,7 @@ def __init__(self, domain, codomain, twist=None): except NotImplementedError: pass else: - from sage.rings.function_field.maps import FunctionFieldDerivation_inseparable + from sage.rings.function_field.derivations import FunctionFieldDerivation_inseparable M, f, self._t = domain.separable_model() self._base_derivation = RingDerivationModule(M, defining_morphism * f) self._d = self._base_derivation(None) diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py new file mode 100644 index 00000000000..efa59c00bfa --- /dev/null +++ b/src/sage/rings/function_field/derivations.py @@ -0,0 +1,1084 @@ +r""" +Derivations of function fields + +For global function fields, which have positive characteristics, the higher +derivation is available:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h(y^2, 2) # optional - sage.libs.pari + ((x^7 + 1)/x^2)*y^2 + x^3*y + +AUTHORS: + +- William Stein (2010): initial version + +- Julian Rüth (2011-09-14, 2014-06-23, 2017-08-21): refactored class hierarchy; added + derivation classes; morphisms to/from fraction fields + +- Kwankyu Lee (2017-04-30): added higher derivations and completions + +""" + +from sage.arith.misc import binomial +from sage.categories.homset import Hom +from sage.categories.map import Map +from sage.categories.sets_cat import Sets +from sage.rings.derivation import RingDerivationWithoutTwist + + +class FunctionFieldDerivation(RingDerivationWithoutTwist): + r""" + Base class for derivations on function fields. + + A derivation on `R` is a map `R \to R` with + `D(\alpha+\beta)=D(\alpha)+D(\beta)` and `D(\alpha\beta)=\beta + D(\alpha)+\alpha D(\beta)` for all `\alpha,\beta\in R`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d/dx + """ + def __init__(self, parent): + r""" + Initialize a derivation. + + INPUT: + + - ``parent`` -- the differential module in which this + derivation lives + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: TestSuite(d).run() + """ + RingDerivationWithoutTwist.__init__(self, parent) + self.__field = parent.domain() + + def is_injective(self) -> bool: + r""" + Return ``False`` since a derivation is never injective. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d.is_injective() + False + """ + return False + + def _rmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d/dx + sage: x * d + x*d/dx + """ + return self._lmul_(factor) + + +class FunctionFieldDerivation_rational(FunctionFieldDerivation): + """ + Derivations on rational function fields. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.derivation() + d/dx + """ + def __init__(self, parent, u=None): + """ + Initialize a derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``u`` -- a parameter describing the derivation + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: TestSuite(d).run() + + The parameter ``u`` can be the name of the variable:: + + sage: K.derivation(x) + d/dx + + or a list of length one whose unique element is the image + of the generator of the underlying function field:: + + sage: K.derivation([x^2]) + x^2*d/dx + """ + FunctionFieldDerivation.__init__(self, parent) + if u is None or u == parent.domain().gen(): + self._u = parent.codomain().one() + elif u == 0 or isinstance(u, (list, tuple)): + if u == 0 or len(u) == 0: + self._u = parent.codomain().zero() + elif len(u) == 1: + self._u = parent.codomain()(u[0]) + else: + raise ValueError("the length does not match") + else: + raise ValueError("you must pass in either a name of a variable or a list of coefficients") + + def _call_(self, x): + """ + Compute the derivation of ``x``. + + INPUT: + + - ``x`` -- element of the rational function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d(x) # indirect doctest + 1 + sage: d(x^3) + 3*x^2 + sage: d(1/x) + -1/x^2 + """ + f = x.numerator() + g = x.denominator() + numerator = f.derivative() * g - f * g.derivative() + if numerator.is_zero(): + return self.codomain().zero() + else: + v = numerator / g**2 + defining_morphism = self.parent()._defining_morphism + if defining_morphism is not None: + v = defining_morphism(v) + return self._u * v + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d + 2*d/dx + """ + return type(self)(self.parent(), [self._u + other._u]) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d/dx + sage: x * d + x*d/dx + """ + return type(self)(self.parent(), [factor * self._u]) + + +class FunctionFieldDerivation_separable(FunctionFieldDerivation): + """ + Derivations of separable extensions. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: L.derivation() + d/dx + """ + def __init__(self, parent, d): + """ + Initialize a derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``d`` -- a variable name or a derivation over + the base field (or something capable to create + such a derivation) + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: TestSuite(d).run() + + sage: L.derivation(y) # d/dy + 2*y*d/dx + + sage: dK = K.derivation([x]); dK + x*d/dx + sage: L.derivation(dK) + x*d/dx + """ + FunctionFieldDerivation.__init__(self, parent) + L = parent.domain() + C = parent.codomain() + dm = parent._defining_morphism + u = L.gen() + if d == L.gen(): + d = parent._base_derivation(None) + f = L.polynomial().change_ring(L) + coeff = -f.derivative()(u) / f.map_coefficients(d)(u) + if dm is not None: + coeff = dm(coeff) + self._d = parent._base_derivation([coeff]) + self._gen_image = C.one() + else: + if isinstance(d, RingDerivationWithoutTwist) and d.domain() is L.base_ring(): + self._d = d + else: + self._d = d = parent._base_derivation(d) + f = L.polynomial() + if dm is None: + denom = f.derivative()(u) + else: + u = dm(u) + denom = f.derivative().map_coefficients(dm, new_base_ring=C)(u) + num = f.map_coefficients(d, new_base_ring=C)(u) + self._gen_image = -num / denom + + def _call_(self, x): + r""" + Evaluate the derivation on ``x``. + + INPUT: + + - ``x`` -- element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d(x) # indirect doctest + 1 + sage: d(y) + 1/2/x*y + sage: d(y^2) + 1 + """ + parent = self.parent() + if x.is_zero(): + return parent.codomain().zero() + x = x._x + y = parent.domain().gen() + dm = parent._defining_morphism + tmp1 = x.map_coefficients(self._d, new_base_ring=parent.codomain()) + tmp2 = x.derivative()(y) + if dm is not None: + tmp2 = dm(tmp2) + y = dm(y) + return tmp1(y) + tmp2 * self._gen_image + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d + d/dx + sage: d + d + 2*d/dx + """ + return type(self)(self.parent(), self._d + other._d) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d + d/dx + sage: y * d + y*d/dx + """ + return type(self)(self.parent(), factor * self._d) + + +class FunctionFieldDerivation_inseparable(FunctionFieldDerivation): + def __init__(self, parent, u=None): + r""" + Initialize this derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``u`` -- a parameter describing the derivation + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + + This also works for iterated non-monic extensions:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari + sage: M.derivation() # optional - sage.libs.pari + d/dz + + We can also create a multiple of the canonical derivation:: + + sage: M.derivation([x]) # optional - sage.libs.pari + x*d/dz + """ + FunctionFieldDerivation.__init__(self, parent) + if u is None: + self._u = parent.codomain().one() + elif u == 0 or isinstance(u, (list, tuple)): + if u == 0 or len(u) == 0: + self._u = parent.codomain().zero() + elif len(u) == 1: + self._u = parent.codomain()(u[0]) + else: + raise ValueError("the length does not match") + else: + raise ValueError("you must pass in either a name of a variable or a list of coefficients") + + def _call_(self, x): + r""" + Evaluate the derivation on ``x``. + + INPUT: + + - ``x`` -- an element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d(x) # indirect doctest # optional - sage.libs.pari + 0 + sage: d(y) # optional - sage.libs.pari + 1 + sage: d(y^2) # optional - sage.libs.pari + 0 + + """ + if x.is_zero(): + return self.codomain().zero() + parent = self.parent() + return self._u * parent._d(parent._t(x)) + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari + d/dy + sage: d + d # optional - sage.libs.pari + 2*d/dy + """ + return type(self)(self.parent(), [self._u + other._u]) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari + d/dy + sage: y * d # optional - sage.libs.pari + y*d/dy + """ + return type(self)(self.parent(), [factor * self._u]) + + +class FunctionFieldHigherDerivation(Map): + """ + Base class of higher derivations on function fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.higher_derivation() # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + """ + Map.__init__(self, Hom(field, field, Sets())) + self._field = field + # elements of a prime finite field do not have pth_root method + if field.constant_base_field().is_prime_field(): + self._pth_root_func = _pth_root_in_prime_field + else: + self._pth_root_func = _pth_root_in_finite_field + + def _repr_type(self) -> str: + """ + Return a string containing the type of the map. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # indirect doctest # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + """ + return 'Higher derivation' + + def __eq__(self, other) -> bool: + """ + Test if ``self`` equals ``other``. + + TESTS:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: loads(dumps(h)) == h # optional - sage.libs.pari + True + """ + if isinstance(other, FunctionFieldHigherDerivation): + return self._field == other._field + return False + + +def _pth_root_in_prime_field(e): + """ + Return the `p`-th root of element ``e`` in a prime finite field. + + TESTS:: + + sage: from sage.rings.function_field.maps import _pth_root_in_prime_field + sage: p = 5 + sage: F. = GF(p) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari + True + """ + return e + + +def _pth_root_in_finite_field(e): + """ + Return the `p`-th root of element ``e`` in a finite field. + + TESTS:: + + sage: from sage.rings.function_field.maps import _pth_root_in_finite_field + sage: p = 3 + sage: F. = GF(p^2) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari + True + """ + return e.pth_root() + + +class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): + """ + Higher derivations of rational function fields over finite fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + sage: h(x^2,2) # optional - sage.libs.pari + 1 + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + """ + FunctionFieldHigherDerivation.__init__(self, field) + + self._p = field.characteristic() + self._separating_element = field.gen() + + def _call_with_args(self, f, args=(), kwds={}): + """ + Call the derivation with args and kwds. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari + 1 + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return the `i`-th derivative of ``f`` with respect to the + separating element. + + This implements Hess' Algorithm 26 in [Hes2002b]_. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._derive(x^3,0) # optional - sage.libs.pari + x^3 + sage: h._derive(x^3,1) # optional - sage.libs.pari + x^2 + sage: h._derive(x^3,2) # optional - sage.libs.pari + x + sage: h._derive(x^3,3) # optional - sage.libs.pari + 1 + sage: h._derive(x^3,4) # optional - sage.libs.pari + 0 + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + prime_power_representation = self._prime_power_representation + + def derive(f, i): + # Step 1: zero-th derivative + if i == 0: + return f + # Step 2: + s = i % p + r = i // p + # Step 3: + e = f + while s > 0: + e = derivative(e) / F(s) + s -= 1 + # Step 4: + if r == 0: + return e + else: + # Step 5: + lambdas = prime_power_representation(e, x) + # Step 6 and 7: + der = 0 + for i in range(p): + mu = derive(lambdas[i], r) + der += mu**p * x**i + return der + + return derive(f, i) + + def _prime_power_representation(self, f, separating_element=None): + """ + Return `p`-th power representation of the element ``f``. + + Here `p` is the characteristic of the function field. + + This implements Hess' Algorithm 25. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari + [x + 1, 1] + sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari + True + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + # Step 1: + a = [f] + aprev = f + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + # Step 2: + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) + for i in range(j + 1, p)) + j -= 1 + # Step 3 + return [self._pth_root(c) for c in b] + + def _pth_root(self, c): + """ + Return the `p`-th root of the rational function ``c``. + + INPUT: + + - ``c`` -- rational function + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari + x^2 + 1 + """ + K = self._field + p = self._p + + R = K._field.ring() + + poly = c.numerator() + num = R([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + poly = c.denominator() + den = R([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + return K.element_class(K, num / den) + + +class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): + """ + Higher derivations of global function fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari, sage.modules + Higher derivation map: + From: Function field in y defined by y^3 + x^3*y + x + To: Function field in y defined by y^3 + x^3*y + x + sage: h(y^2, 2) # optional - sage.libs.pari, sage.modules + ((x^7 + 1)/x^2)*y^2 + x^3*y + """ + + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari, sage.modules + """ + from sage.matrix.constructor import matrix + + FunctionFieldHigherDerivation.__init__(self, field) + + self._p = field.characteristic() + self._separating_element = field(field.base_field().gen()) + + p = field.characteristic() + y = field.gen() + + # matrix for pth power map; used in _prime_power_representation method + self.__pth_root_matrix = matrix([(y**(i * p)).list() + for i in range(field.degree())]).transpose() + + # cache computed higher derivatives to speed up later computations + self._cache = {} + + def _call_with_args(self, f, args, kwds): + """ + Call the derivation with ``args`` and ``kwds``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari, sage.modules + ((x^7 + 1)/x^2)*y^2 + x^3*y + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return ``i``-th derivative of ``f`` with respect to the separating + element. + + This implements Hess' Algorithm 26 in [Hes2002b]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: y^3 # optional - sage.libs.pari, sage.modules + x^3*y + x + sage: h._derive(y^3,0) # optional - sage.libs.pari, sage.modules + x^3*y + x + sage: h._derive(y^3,1) # optional - sage.libs.pari, sage.modules + x^4*y^2 + 1 + sage: h._derive(y^3,2) # optional - sage.libs.pari, sage.modules + x^10*y^2 + (x^8 + x)*y + sage: h._derive(y^3,3) # optional - sage.libs.pari, sage.modules + (x^9 + x^2)*y^2 + x^7*y + sage: h._derive(y^3,4) # optional - sage.libs.pari, sage.modules + (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y + """ + F = self._field + p = self._p + frob = F.frobenius_endomorphism() # p-th power map + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + try: + cache = self._cache[separating_element] + except KeyError: + cache = self._cache[separating_element] = {} + + def derive(f, i): + # Step 1: zero-th derivative + if i == 0: + return f + + # Step 1.5: use cached result if available + try: + return cache[f, i] + except KeyError: + pass + + # Step 2: + s = i % p + r = i // p + # Step 3: + e = f + while s > 0: + e = derivative(e) / F(s) + s -= 1 + # Step 4: + if r == 0: + der = e + else: + # Step 5: inlined self._prime_power_representation + a = [e] + aprev = e + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(k, j) * b[k] * x**(k - j) + for k in range(j + 1, p)) + j -= 1 + lambdas = [self._pth_root(c) for c in b] + + # Step 6 and 7: + der = 0 + xpow = 1 + for k in range(p): + mu = derive(lambdas[k], r) + der += frob(mu) * xpow + xpow *= x + + cache[f, i] = der + return der + + return derive(f, i) + + def _prime_power_representation(self, f, separating_element=None): + """ + Return `p`-th power representation of the element ``f``. + + Here `p` is the characteristic of the function field. + + This implements Hess' Algorithm 25 in [Hes2002b]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: b = h._prime_power_representation(y) # optional - sage.libs.pari, sage.modules + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari, sage.modules + True + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + # Step 1: + a = [f] + aprev = f + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + # Step 2: + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) + for i in range(j + 1, p)) + j -= 1 + # Step 3 + return [self._pth_root(c) for c in b] + + def _pth_root(self, c): + """ + Return the `p`-th root of function field element ``c``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari, sage.modules + y^2 + x^2 + """ + from sage.modules.free_module_element import vector + + K = self._field.base_field() # rational function field + p = self._p + + coeffs = [] + for d in self.__pth_root_matrix.solve_right(vector(c.list())): + poly = d.numerator() + num = K([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + poly = d.denominator() + den = K([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + coeffs.append(num / den) + return self._field(coeffs) + + +class FunctionFieldHigherDerivation_char_zero(FunctionFieldHigherDerivation): + """ + Higher derivations of function fields of characteristic zero. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: h + Higher derivation map: + From: Function field in y defined by y^3 + x^3*y + x + To: Function field in y defined by y^3 + x^3*y + x + sage: h(y,1) == -(3*x^2*y+1)/(3*y^2+x^3) + True + sage: h(y^2,1) == -2*y*(3*x^2*y+1)/(3*y^2+x^3) + True + sage: e = L.random_element() + sage: h(h(e,1),1) == 2*h(e,2) + True + sage: h(h(h(e,1),1),1) == 3*2*h(e,3) + True + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: TestSuite(h).run(skip=['_test_category']) + """ + FunctionFieldHigherDerivation.__init__(self, field) + + self._separating_element = field(field.base_field().gen()) + + # cache computed higher derivatives to speed up later computations + self._cache = {} + + def _call_with_args(self, f, args, kwds): + """ + Call the derivation with ``args`` and ``kwds``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: e = L.random_element() + sage: h(h(e,1),1) == 2*h(e,2) # indirect doctest + True + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return ``i``-th derivative of ``f`` with respect to the separating + element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: y^3 + -x^3*y - x + sage: h._derive(y^3,0) + -x^3*y - x + sage: h._derive(y^3,1) + (-21/4*x^4/(x^7 + 27/4))*y^2 + ((-9/2*x^9 - 45/2*x^2)/(x^7 + 27/4))*y + (-9/2*x^7 - 27/4)/(x^7 + 27/4) + """ + F = self._field + + if separating_element is None: + x = self._separating_element + xderinv = 1 + else: + x = separating_element + xderinv = ~(x.derivative()) + + try: + cache = self._cache[separating_element] + except KeyError: + cache = self._cache[separating_element] = {} + + if i == 0: + return f + + try: + return cache[f, i] + except KeyError: + pass + + s = i + e = f + while s > 0: + e = xderinv * e.derivative() / F(s) + s -= 1 + + der = e + + cache[f, i] = der + return der diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index dbbf63c85dd..784ae3d7c0a 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -221,10 +221,9 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.cachefunc import cached_method - from sage.arith.functions import lcm - +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer from sage.rings.ring import Field from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -234,13 +233,12 @@ from sage.categories.function_fields import FunctionFields from sage.structure.category_object import CategoryObject -from .differential import DifferentialsSpace, DifferentialsSpace_global - from .element import ( FunctionFieldElement, FunctionFieldElement_rational, FunctionFieldElement_polymod) + def is_FunctionField(x): """ Return ``True`` if ``x`` is a function field. @@ -274,7 +272,7 @@ class FunctionField(Field): sage: K Rational function field in x over Rational Field """ - _differentials_space = DifferentialsSpace + _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace') def __init__(self, base_field, names, category=FunctionFields()): """ @@ -3070,7 +3068,7 @@ def higher_derivation(self): From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) """ - from .maps import FunctionFieldHigherDerivation_char_zero + from .derivations import FunctionFieldHigherDerivation_char_zero return FunctionFieldHigherDerivation_char_zero(self) @@ -3105,7 +3103,7 @@ class FunctionField_global(FunctionField_simple): sage: L.genus() # optional - sage.libs.pari 0 """ - _differentials_space = DifferentialsSpace_global + _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace_global') def __init__(self, polynomial, names): """ @@ -3154,7 +3152,7 @@ def higher_derivation(self): From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ - from .maps import FunctionFieldHigherDerivation_global + from .derivations import FunctionFieldHigherDerivation_global return FunctionFieldHigherDerivation_global(self) def get_place(self, degree): @@ -4551,7 +4549,7 @@ def higher_derivation(self): sage: [d(x^9,i) for i in range(10)] [x^9, 9*x^8, 36*x^7, 84*x^6, 126*x^5, 126*x^4, 84*x^3, 36*x^2, 9*x, 1] """ - from .maps import FunctionFieldHigherDerivation_char_zero + from .derivations import FunctionFieldHigherDerivation_char_zero return FunctionFieldHigherDerivation_char_zero(self) @@ -4559,7 +4557,7 @@ class RationalFunctionField_global(RationalFunctionField): """ Rational function field over finite fields. """ - _differentials_space = DifferentialsSpace_global + _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace_global') def places(self, degree=1): """ @@ -4681,5 +4679,5 @@ def higher_derivation(self): sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] """ - from .maps import RationalFunctionFieldHigherDerivation_global + from .derivations import RationalFunctionFieldHigherDerivation_global return RationalFunctionFieldHigherDerivation_global(self) diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 2e6c7cd0002..c38c63d36b0 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -25,15 +25,6 @@ ... ValueError: invalid morphism -For global function fields, which have positive characteristics, the higher -derivation is available:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h(y^2, 2) # optional - sage.libs.pari - ((x^7 + 1)/x^2)*y^2 + x^3*y - AUTHORS: - William Stein (2010): initial version @@ -54,1070 +45,24 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.arith.misc import binomial from sage.categories.homset import Hom from sage.categories.map import Map from sage.categories.morphism import Morphism, SetMorphism -from sage.categories.sets_cat import Sets -from sage.rings.derivation import RingDerivationWithoutTwist +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.morphism import RingHomomorphism -class FunctionFieldDerivation(RingDerivationWithoutTwist): - r""" - Base class for derivations on function fields. - - A derivation on `R` is a map `R \to R` with - `D(\alpha+\beta)=D(\alpha)+D(\beta)` and `D(\alpha\beta)=\beta - D(\alpha)+\alpha D(\beta)` for all `\alpha,\beta\in R`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d - d/dx - """ - def __init__(self, parent): - r""" - Initialize a derivation. - - INPUT: - - - ``parent`` -- the differential module in which this - derivation lives - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: TestSuite(d).run() - """ - RingDerivationWithoutTwist.__init__(self, parent) - self.__field = parent.domain() - - def is_injective(self) -> bool: - r""" - Return ``False`` since a derivation is never injective. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d.is_injective() - False - """ - return False - - def _rmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d - d/dx - sage: x * d - x*d/dx - """ - return self._lmul_(factor) - - -class FunctionFieldDerivation_rational(FunctionFieldDerivation): - """ - Derivations on rational function fields. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.derivation() - d/dx - """ - def __init__(self, parent, u=None): - """ - Initialize a derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``u`` -- a parameter describing the derivation - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: TestSuite(d).run() - - The parameter ``u`` can be the name of the variable:: - - sage: K.derivation(x) - d/dx - - or a list of length one whose unique element is the image - of the generator of the underlying function field:: - - sage: K.derivation([x^2]) - x^2*d/dx - """ - FunctionFieldDerivation.__init__(self, parent) - if u is None or u == parent.domain().gen(): - self._u = parent.codomain().one() - elif u == 0 or isinstance(u, (list, tuple)): - if u == 0 or len(u) == 0: - self._u = parent.codomain().zero() - elif len(u) == 1: - self._u = parent.codomain()(u[0]) - else: - raise ValueError("the length does not match") - else: - raise ValueError("you must pass in either a name of a variable or a list of coefficients") - - def _call_(self, x): - """ - Compute the derivation of ``x``. - - INPUT: - - - ``x`` -- element of the rational function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d(x) # indirect doctest - 1 - sage: d(x^3) - 3*x^2 - sage: d(1/x) - -1/x^2 - """ - f = x.numerator() - g = x.denominator() - numerator = f.derivative() * g - f * g.derivative() - if numerator.is_zero(): - return self.codomain().zero() - else: - v = numerator / g**2 - defining_morphism = self.parent()._defining_morphism - if defining_morphism is not None: - v = defining_morphism(v) - return self._u * v - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d + d - 2*d/dx - """ - return type(self)(self.parent(), [self._u + other._u]) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d - d/dx - sage: x * d - x*d/dx - """ - return type(self)(self.parent(), [factor * self._u]) - - -class FunctionFieldDerivation_separable(FunctionFieldDerivation): - """ - Derivations of separable extensions. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L.derivation() - d/dx - """ - def __init__(self, parent, d): - """ - Initialize a derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``d`` -- a variable name or a derivation over - the base field (or something capable to create - such a derivation) - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: TestSuite(d).run() - - sage: L.derivation(y) # d/dy - 2*y*d/dx - - sage: dK = K.derivation([x]); dK - x*d/dx - sage: L.derivation(dK) - x*d/dx - """ - FunctionFieldDerivation.__init__(self, parent) - L = parent.domain() - C = parent.codomain() - dm = parent._defining_morphism - u = L.gen() - if d == L.gen(): - d = parent._base_derivation(None) - f = L.polynomial().change_ring(L) - coeff = -f.derivative()(u) / f.map_coefficients(d)(u) - if dm is not None: - coeff = dm(coeff) - self._d = parent._base_derivation([coeff]) - self._gen_image = C.one() - else: - if isinstance(d, RingDerivationWithoutTwist) and d.domain() is L.base_ring(): - self._d = d - else: - self._d = d = parent._base_derivation(d) - f = L.polynomial() - if dm is None: - denom = f.derivative()(u) - else: - u = dm(u) - denom = f.derivative().map_coefficients(dm, new_base_ring=C)(u) - num = f.map_coefficients(d, new_base_ring=C)(u) - self._gen_image = -num / denom - - def _call_(self, x): - r""" - Evaluate the derivation on ``x``. - - INPUT: - - - ``x`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d(x) # indirect doctest - 1 - sage: d(y) - 1/2/x*y - sage: d(y^2) - 1 - """ - parent = self.parent() - if x.is_zero(): - return parent.codomain().zero() - x = x._x - y = parent.domain().gen() - dm = parent._defining_morphism - tmp1 = x.map_coefficients(self._d, new_base_ring=parent.codomain()) - tmp2 = x.derivative()(y) - if dm is not None: - tmp2 = dm(tmp2) - y = dm(y) - return tmp1(y) + tmp2 * self._gen_image - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d - d/dx - sage: d + d - 2*d/dx - """ - return type(self)(self.parent(), self._d + other._d) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d - d/dx - sage: y * d - y*d/dx - """ - return type(self)(self.parent(), factor * self._d) - - -class FunctionFieldDerivation_inseparable(FunctionFieldDerivation): - def __init__(self, parent, u=None): - r""" - Initialize this derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``u`` -- a parameter describing the derivation - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - - This also works for iterated non-monic extensions:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari - sage: M.derivation() # optional - sage.libs.pari - d/dz - - We can also create a multiple of the canonical derivation:: - - sage: M.derivation([x]) # optional - sage.libs.pari - x*d/dz - """ - FunctionFieldDerivation.__init__(self, parent) - if u is None: - self._u = parent.codomain().one() - elif u == 0 or isinstance(u, (list, tuple)): - if u == 0 or len(u) == 0: - self._u = parent.codomain().zero() - elif len(u) == 1: - self._u = parent.codomain()(u[0]) - else: - raise ValueError("the length does not match") - else: - raise ValueError("you must pass in either a name of a variable or a list of coefficients") - - def _call_(self, x): - r""" - Evaluate the derivation on ``x``. - - INPUT: - - - ``x`` -- an element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d(x) # indirect doctest # optional - sage.libs.pari - 0 - sage: d(y) # optional - sage.libs.pari - 1 - sage: d(y^2) # optional - sage.libs.pari - 0 - - """ - if x.is_zero(): - return self.codomain().zero() - parent = self.parent() - return self._u * parent._d(parent._t(x)) - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari - d/dy - sage: d + d # optional - sage.libs.pari - 2*d/dy - """ - return type(self)(self.parent(), [self._u + other._u]) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari - d/dy - sage: y * d # optional - sage.libs.pari - y*d/dy - """ - return type(self)(self.parent(), [factor * self._u]) - - -class FunctionFieldHigherDerivation(Map): - """ - Base class of higher derivations on function fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.higher_derivation() # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari - """ - Map.__init__(self, Hom(field, field, Sets())) - self._field = field - # elements of a prime finite field do not have pth_root method - if field.constant_base_field().is_prime_field(): - self._pth_root_func = _pth_root_in_prime_field - else: - self._pth_root_func = _pth_root_in_finite_field - - def _repr_type(self) -> str: - """ - Return a string containing the type of the map. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # indirect doctest # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - """ - return 'Higher derivation' - - def __eq__(self, other) -> bool: - """ - Test if ``self`` equals ``other``. - - TESTS:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: loads(dumps(h)) == h # optional - sage.libs.pari - True - """ - if isinstance(other, FunctionFieldHigherDerivation): - return self._field == other._field - return False - - -def _pth_root_in_prime_field(e): - """ - Return the `p`-th root of element ``e`` in a prime finite field. - - TESTS:: - - sage: from sage.rings.function_field.maps import _pth_root_in_prime_field - sage: p = 5 - sage: F. = GF(p) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari - True - """ - return e - - -def _pth_root_in_finite_field(e): - """ - Return the `p`-th root of element ``e`` in a finite field. - - TESTS:: - - sage: from sage.rings.function_field.maps import _pth_root_in_finite_field - sage: p = 3 - sage: F. = GF(p^2) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari - True - """ - return e.pth_root() - - -class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): - """ - Higher derivations of rational function fields over finite fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - sage: h(x^2,2) # optional - sage.libs.pari - 1 - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari - """ - FunctionFieldHigherDerivation.__init__(self, field) - - self._p = field.characteristic() - self._separating_element = field.gen() - - def _call_with_args(self, f, args=(), kwds={}): - """ - Call the derivation with args and kwds. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari - 1 - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return the `i`-th derivative of ``f`` with respect to the - separating element. - - This implements Hess' Algorithm 26 in [Hes2002b]_. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._derive(x^3,0) # optional - sage.libs.pari - x^3 - sage: h._derive(x^3,1) # optional - sage.libs.pari - x^2 - sage: h._derive(x^3,2) # optional - sage.libs.pari - x - sage: h._derive(x^3,3) # optional - sage.libs.pari - 1 - sage: h._derive(x^3,4) # optional - sage.libs.pari - 0 - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - prime_power_representation = self._prime_power_representation - - def derive(f, i): - # Step 1: zero-th derivative - if i == 0: - return f - # Step 2: - s = i % p - r = i // p - # Step 3: - e = f - while s > 0: - e = derivative(e) / F(s) - s -= 1 - # Step 4: - if r == 0: - return e - else: - # Step 5: - lambdas = prime_power_representation(e, x) - # Step 6 and 7: - der = 0 - for i in range(p): - mu = derive(lambdas[i], r) - der += mu**p * x**i - return der - - return derive(f, i) - - def _prime_power_representation(self, f, separating_element=None): - """ - Return `p`-th power representation of the element ``f``. - - Here `p` is the characteristic of the function field. - - This implements Hess' Algorithm 25. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari - [x + 1, 1] - sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari - True - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - # Step 1: - a = [f] - aprev = f - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - # Step 2: - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) - for i in range(j + 1, p)) - j -= 1 - # Step 3 - return [self._pth_root(c) for c in b] - - def _pth_root(self, c): - """ - Return the `p`-th root of the rational function ``c``. - - INPUT: - - - ``c`` -- rational function - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari - x^2 + 1 - """ - K = self._field - p = self._p - - R = K._field.ring() - - poly = c.numerator() - num = R([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - poly = c.denominator() - den = R([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - return K.element_class(K, num / den) - - -class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): - """ - Higher derivations of global function fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari, sage.modules - Higher derivation map: - From: Function field in y defined by y^3 + x^3*y + x - To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) # optional - sage.libs.pari, sage.modules - ((x^7 + 1)/x^2)*y^2 + x^3*y - """ - - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari, sage.modules - """ - from sage.matrix.constructor import matrix - - FunctionFieldHigherDerivation.__init__(self, field) - - self._p = field.characteristic() - self._separating_element = field(field.base_field().gen()) - - p = field.characteristic() - y = field.gen() - - # matrix for pth power map; used in _prime_power_representation method - self.__pth_root_matrix = matrix([(y**(i * p)).list() - for i in range(field.degree())]).transpose() - - # cache computed higher derivatives to speed up later computations - self._cache = {} - - def _call_with_args(self, f, args, kwds): - """ - Call the derivation with ``args`` and ``kwds``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari, sage.modules - ((x^7 + 1)/x^2)*y^2 + x^3*y - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return ``i``-th derivative of ``f`` with respect to the separating - element. - - This implements Hess' Algorithm 26 in [Hes2002b]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: y^3 # optional - sage.libs.pari, sage.modules - x^3*y + x - sage: h._derive(y^3,0) # optional - sage.libs.pari, sage.modules - x^3*y + x - sage: h._derive(y^3,1) # optional - sage.libs.pari, sage.modules - x^4*y^2 + 1 - sage: h._derive(y^3,2) # optional - sage.libs.pari, sage.modules - x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) # optional - sage.libs.pari, sage.modules - (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) # optional - sage.libs.pari, sage.modules - (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y - """ - F = self._field - p = self._p - frob = F.frobenius_endomorphism() # p-th power map - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - try: - cache = self._cache[separating_element] - except KeyError: - cache = self._cache[separating_element] = {} - - def derive(f, i): - # Step 1: zero-th derivative - if i == 0: - return f - - # Step 1.5: use cached result if available - try: - return cache[f, i] - except KeyError: - pass - - # Step 2: - s = i % p - r = i // p - # Step 3: - e = f - while s > 0: - e = derivative(e) / F(s) - s -= 1 - # Step 4: - if r == 0: - der = e - else: - # Step 5: inlined self._prime_power_representation - a = [e] - aprev = e - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(k, j) * b[k] * x**(k - j) - for k in range(j + 1, p)) - j -= 1 - lambdas = [self._pth_root(c) for c in b] - - # Step 6 and 7: - der = 0 - xpow = 1 - for k in range(p): - mu = derive(lambdas[k], r) - der += frob(mu) * xpow - xpow *= x - - cache[f, i] = der - return der - - return derive(f, i) - - def _prime_power_representation(self, f, separating_element=None): - """ - Return `p`-th power representation of the element ``f``. - - Here `p` is the characteristic of the function field. - - This implements Hess' Algorithm 25 in [Hes2002b]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: b = h._prime_power_representation(y) # optional - sage.libs.pari, sage.modules - sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari, sage.modules - True - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - # Step 1: - a = [f] - aprev = f - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - # Step 2: - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) - for i in range(j + 1, p)) - j -= 1 - # Step 3 - return [self._pth_root(c) for c in b] - - def _pth_root(self, c): - """ - Return the `p`-th root of function field element ``c``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari, sage.modules - y^2 + x^2 - """ - from sage.modules.free_module_element import vector - - K = self._field.base_field() # rational function field - p = self._p - - coeffs = [] - for d in self.__pth_root_matrix.solve_right(vector(c.list())): - poly = d.numerator() - num = K([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - poly = d.denominator() - den = K([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - coeffs.append(num / den) - return self._field(coeffs) - - -class FunctionFieldHigherDerivation_char_zero(FunctionFieldHigherDerivation): - """ - Higher derivations of function fields of characteristic zero. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: h - Higher derivation map: - From: Function field in y defined by y^3 + x^3*y + x - To: Function field in y defined by y^3 + x^3*y + x - sage: h(y,1) == -(3*x^2*y+1)/(3*y^2+x^3) - True - sage: h(y^2,1) == -2*y*(3*x^2*y+1)/(3*y^2+x^3) - True - sage: e = L.random_element() - sage: h(h(e,1),1) == 2*h(e,2) - True - sage: h(h(h(e,1),1),1) == 3*2*h(e,3) - True - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: TestSuite(h).run(skip=['_test_category']) - """ - FunctionFieldHigherDerivation.__init__(self, field) - - self._separating_element = field(field.base_field().gen()) - - # cache computed higher derivatives to speed up later computations - self._cache = {} - - def _call_with_args(self, f, args, kwds): - """ - Call the derivation with ``args`` and ``kwds``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: e = L.random_element() - sage: h(h(e,1),1) == 2*h(e,2) # indirect doctest - True - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return ``i``-th derivative of ``f`` with respect to the separating - element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: y^3 - -x^3*y - x - sage: h._derive(y^3,0) - -x^3*y - x - sage: h._derive(y^3,1) - (-21/4*x^4/(x^7 + 27/4))*y^2 + ((-9/2*x^9 - 45/2*x^2)/(x^7 + 27/4))*y + (-9/2*x^7 - 27/4)/(x^7 + 27/4) - """ - F = self._field - - if separating_element is None: - x = self._separating_element - xderinv = 1 - else: - x = separating_element - xderinv = ~(x.derivative()) - - try: - cache = self._cache[separating_element] - except KeyError: - cache = self._cache[separating_element] = {} - - if i == 0: - return f - - try: - return cache[f, i] - except KeyError: - pass - - s = i - e = f - while s > 0: - e = xderinv * e.derivative() / F(s) - s -= 1 - - der = e - - cache[f, i] = der - return der +lazy_import("sage.rings.function_field.derivations", ( + "FunctionFieldDerivation", + "FunctionFieldDerivation_rational", + "FunctionFieldDerivation_separable", + "FunctionFieldDerivation_inseparable", + "FunctionFieldHigherDerivation", + "RationalFunctionFieldHigherDerivation_global", + "FunctionFieldHigherDerivation_global", + "FunctionFieldHigherDerivation_char_zero", +), deprecation=99999) class FunctionFieldVectorSpaceIsomorphism(Morphism): From 64736f36e2c4376ca057ef5c7e89aea092c67e6d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Mar 2023 21:16:38 -0800 Subject: [PATCH 12/54] sage.rings.function_field: Move some imports into methods --- src/sage/rings/function_field/ideal.py | 8 ++++++-- src/sage/rings/function_field/order.py | 14 +++++++++----- src/sage/rings/function_field/place.py | 17 +++++++++++------ 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index cc2de46dad2..44ce467ebf0 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -106,8 +106,6 @@ from sage.rings.infinity import infinity from sage.rings.ideal import Ideal_generic -from .divisor import divisor - class FunctionFieldIdeal(Element): """ @@ -478,6 +476,8 @@ def divisor(self): sage: I.divisor() # optional - sage.libs.pari - Place (1/x, 1/x*y) """ + from .divisor import divisor + if self.is_zero(): raise ValueError("not defined for zero ideal") @@ -510,6 +510,8 @@ def divisor_of_zeros(self): sage: I.divisor_of_zeros() # optional - sage.libs.pari 2*Place (x + 1, x*y) """ + from .divisor import divisor + if self.is_zero(): raise ValueError("not defined for zero ideal") @@ -542,6 +544,8 @@ def divisor_of_poles(self): sage: I.divisor_of_poles() # optional - sage.libs.pari Place (x, x*y) """ + from .divisor import divisor + if self.is_zero(): raise ValueError("not defined for zero ideal") diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index 6d451781142..48044eec3ab 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -109,14 +109,12 @@ from sage.misc.cachefunc import cached_method -from sage.modules.free_module_element import vector from sage.arith.functions import lcm from sage.arith.misc import GCD as gcd from sage.rings.number_field.number_field_base import NumberField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - from sage.structure.parent import Parent from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation @@ -124,7 +122,6 @@ from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.categories.euclidean_domains import EuclideanDomains - from .ideal import ( IdealMonoid, FunctionFieldIdeal, @@ -136,8 +133,6 @@ FunctionFieldIdealInfinite_rational, FunctionFieldIdealInfinite_polymod) -from .hermite_form_polynomial import reversed_hermite_form - class FunctionFieldOrder_base(CachedRepresentation, Parent): """ @@ -1238,7 +1233,9 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): """ FunctionFieldMaximalOrder.__init__(self, field, ideal_class) + from sage.modules.free_module_element import vector from .function_field import FunctionField_integral + if isinstance(field, FunctionField_integral): basis = field._maximal_order_basis() else: @@ -1453,6 +1450,7 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): defined by y^2 + 6*x^3 + 6 """ from sage.matrix.constructor import matrix + from .hermite_form_polynomial import reversed_hermite_form R = self._module_base_ring._ring @@ -1681,6 +1679,8 @@ def _coordinate_vector(self, e): sage: O._coordinate_vector(x*y) # optional - sage.libs.pari, sage.modules (0, x, 0, 0) """ + from sage.modules.free_module_element import vector + v = self._module.coordinate_vector(self._to_module(e), check=False) return vector([c.numerator() for c in v]) @@ -1789,6 +1789,7 @@ def decomposition(self, ideal): """ from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector F = self.function_field() n = F.degree() @@ -1928,6 +1929,7 @@ def p_radical(self, prime): defined by y^3 + x^6 + x^4 + x^2 """ from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector g = prime.gens()[0] @@ -2060,6 +2062,7 @@ def decomposition(self, ideal): # Buchman-Lenstra algorithm # ############################# from sage.matrix.special import block_matrix + from sage.modules.free_module_element import vector pO = self.ideal(p) Ip = self.p_radical(ideal) @@ -2604,6 +2607,7 @@ def ideal_with_gens_over_base(self, gens): # factors removed. For a fractional ideal, we also need to find # the largest factor x^m that divides the denominator. from sage.matrix.special import block_matrix + from .hermite_form_polynomial import reversed_hermite_form d = ideal.denominator() h = ideal.hnf() diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 88b93556232..6a28865041b 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -55,12 +55,13 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +import sage.rings.abc + from sage.misc.cachefunc import cached_method from sage.arith.functions import lcm from sage.rings.integer_ring import ZZ -from sage.rings.qqbar import QQbar from sage.rings.number_field.number_field_base import NumberField from sage.structure.unique_representation import UniqueRepresentation @@ -70,10 +71,6 @@ from sage.categories.sets_cat import Sets -from sage.modules.free_module_element import vector - -from sage.matrix.constructor import matrix - class FunctionFieldPlace(Element): """ @@ -624,6 +621,8 @@ def _gaps_rational(self): sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.libs.pari [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ + from sage.matrix.constructor import matrix + F = self.function_field() n = F.degree() O = F.maximal_order() @@ -753,6 +752,9 @@ def _gaps_wronskian(self): sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.libs.pari [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + F = self.function_field() R,fr_R,to_R = self._residue_field() der = F.higher_derivation() @@ -918,6 +920,9 @@ def _residue_field(self, name=None): to_K = lambda f: _to_K(to_F(f)) return K, from_K, to_K + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + O = F.maximal_order() Obasis = O.basis() @@ -985,7 +990,7 @@ def candidates(): if a is not None: K,fr_K,_ = self.place_below().residue_field() b = fr_K(K.gen()) - if isinstance(k, NumberField) or k is QQbar: + if isinstance(k, (NumberField, sage.rings.abc.AlgebraicField)): kk = ZZ else: kk = k From 219aedc7e3d7512ec4b0a9a351cb0c6a829c0bd7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Mar 2023 23:29:11 -0800 Subject: [PATCH 13/54] sage.rings.function_field.derivations: Add to docs --- src/doc/en/reference/function_fields/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/en/reference/function_fields/index.rst b/src/doc/en/reference/function_fields/index.rst index 50c04560a33..06a92de1707 100644 --- a/src/doc/en/reference/function_fields/index.rst +++ b/src/doc/en/reference/function_fields/index.rst @@ -18,6 +18,7 @@ algebraic closure of `\QQ`. sage/rings/function_field/divisor sage/rings/function_field/differential sage/rings/function_field/valuation_ring + sage/rings/function_field/derivations sage/rings/function_field/maps sage/rings/function_field/extensions sage/rings/function_field/constructor From d3e9388cfb6be45dbcbb4ef15d6d2cfd6466cd4d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 09:23:58 -0800 Subject: [PATCH 14/54] src/sage/rings/function_field/function_field.py: Fix lazy imports --- src/sage/rings/function_field/function_field.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 784ae3d7c0a..cb6114f80ec 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -223,7 +223,7 @@ # **************************************************************************** from sage.arith.functions import lcm from sage.misc.cachefunc import cached_method -from sage.misc.lazy_import import lazy_import +from sage.misc.lazy_import import LazyImport from sage.rings.integer import Integer from sage.rings.ring import Field from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -272,7 +272,7 @@ class FunctionField(Field): sage: K Rational function field in x over Rational Field """ - _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace') + _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace') def __init__(self, base_field, names, category=FunctionFields()): """ @@ -3103,7 +3103,7 @@ class FunctionField_global(FunctionField_simple): sage: L.genus() # optional - sage.libs.pari 0 """ - _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace_global') + _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') def __init__(self, polynomial, names): """ @@ -4557,7 +4557,7 @@ class RationalFunctionField_global(RationalFunctionField): """ Rational function field over finite fields. """ - _differentials_space = lazy_import('sage.rings.function_field.differential', 'DifferentialsSpace_global') + _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') def places(self, degree=1): """ From 9eb81aaa704ceaa9ccda01c391e1c748ae4d5f03 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 00:57:05 -0800 Subject: [PATCH 15/54] src/sage/rings/function_field/function_field.py: More # optional --- .../rings/function_field/function_field.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index cb6114f80ec..baa7becf571 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -970,12 +970,12 @@ def space_of_differentials(self): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.space_of_differentials() + sage: K.space_of_differentials() # optional - sage.modules Space of differentials of Rational function field in t over Rational Field sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_differentials() # optional - sage.libs.pari + sage: L.space_of_differentials() # optional - sage.libs.pari, sage.modules Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ @@ -988,7 +988,7 @@ def space_of_holomorphic_differentials(self): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.space_of_holomorphic_differentials() + sage: K.space_of_holomorphic_differentials() # optional - sage.modules (Vector space of dimension 0 over Rational Field, Linear map: From: Vector space of dimension 0 over Rational Field @@ -999,7 +999,7 @@ def space_of_holomorphic_differentials(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari + sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari, sage.modules (Vector space of dimension 4 over Finite Field of size 5, Linear map: From: Vector space of dimension 4 over Finite Field of size 5 @@ -1026,7 +1026,7 @@ def basis_of_holomorphic_differentials(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari + sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari, sage.modules [((x/(x^3 + 4))*y) d(x), ((1/(x^3 + 4))*y) d(x), ((x/(x^3 + 4))*y^2) d(x), @@ -1053,7 +1053,7 @@ def divisor_group(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.divisor_group() # optional - sage.libs.pari + sage: L.divisor_group() # optional - sage.libs.pari, sage.modules Divisor group of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ from .divisor import DivisorGroup @@ -4190,7 +4190,7 @@ def free_module(self, base=None, basis=None, map=True): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.free_module() + sage: K.free_module() # optional - sage.modules (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: From: Vector space of dimension 1 over Rational function field in x over Rational Field To: Rational function field in x over Rational Field, Isomorphism: @@ -4199,7 +4199,7 @@ def free_module(self, base=None, basis=None, map=True): TESTS:: - sage: K.free_module() + sage: K.free_module() # optional - sage.modules (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: From: Vector space of dimension 1 over Rational function field in x over Rational Field To: Rational function field in x over Rational Field, Isomorphism: @@ -4443,7 +4443,7 @@ def different(self): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.different() + sage: K.different() # optional - sage.modules 0 """ return self.divisor_group().zero() @@ -4543,10 +4543,10 @@ def higher_derivation(self): EXAMPLES:: sage: F. = FunctionField(QQ) - sage: d = F.higher_derivation() - sage: [d(x^5,i) for i in range(10)] + sage: d = F.higher_derivation() # optional - sage.modules + sage: [d(x^5,i) for i in range(10)] # optional - sage.modules [x^5, 5*x^4, 10*x^3, 10*x^2, 5*x, 1, 0, 0, 0, 0] - sage: [d(x^9,i) for i in range(10)] + sage: [d(x^9,i) for i in range(10)] # optional - sage.modules [x^9, 9*x^8, 36*x^7, 84*x^6, 126*x^5, 126*x^4, 84*x^3, 36*x^2, 9*x, 1] """ from .derivations import FunctionFieldHigherDerivation_char_zero From 4921648c29657e2122fe067d90713aa3f2d7eb89 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 14:29:35 -0800 Subject: [PATCH 16/54] sage.rings.function_field: Mark doctests # optional - sage.libs.singular etc. --- src/sage/categories/function_fields.py | 8 +- src/sage/rings/function_field/constructor.py | 28 +- src/sage/rings/function_field/element.pyx | 232 +++---- src/sage/rings/function_field/extensions.py | 10 +- .../rings/function_field/function_field.py | 620 +++++++++--------- .../function_field_valuation.py | 110 ++-- src/sage/rings/function_field/ideal.py | 312 ++++----- src/sage/rings/function_field/maps.py | 128 ++-- src/sage/rings/function_field/order.py | 62 +- src/sage/rings/function_field/place.py | 22 +- 10 files changed, 769 insertions(+), 763 deletions(-) diff --git a/src/sage/categories/function_fields.py b/src/sage/categories/function_fields.py index 6c30067e53f..65a108e4565 100644 --- a/src/sage/categories/function_fields.py +++ b/src/sage/categories/function_fields.py @@ -52,14 +52,14 @@ def _call_(self, x): EXAMPLES:: sage: C = FunctionFields() - sage: K.=FunctionField(QQ) + sage: K. = FunctionField(QQ) sage: C(K) Rational function field in x over Rational Field sage: Ky. = K[] - sage: L = K.extension(y^2-x) - sage: C(L) + sage: L = K.extension(y^2 - x) # optional - sage.libs.singular + sage: C(L) # optional - sage.libs.singular Function field in y defined by y^2 - x - sage: C(L.equation_order()) + sage: C(L.equation_order()) # optional - sage.libs.singular Function field in y defined by y^2 - x """ try: diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index 3e6966b8836..8fc3b44c7b3 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -133,9 +133,9 @@ class FunctionFieldExtensionFactory(UniqueFactory): sage: y2 = y*1 sage: y2 is y False - sage: L.=K.extension(x - y^2) - sage: M.=K.extension(x - y2^2) - sage: L is M + sage: L. = K.extension(x - y^2) # optional - sage.libs.singular + sage: M. = K.extension(x - y2^2) # optional - sage.libs.singular + sage: L is M # optional - sage.libs.singular True """ def create_key(self,polynomial,names): @@ -147,7 +147,7 @@ def create_key(self,polynomial,names): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x - y^2) # indirect doctest + sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.libs.singular TESTS: @@ -155,12 +155,12 @@ def create_key(self,polynomial,names): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: R. = L[] - sage: M. = L.extension(z - 1) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z - 1) # optional - sage.libs.singular sage: R. = K[] - sage: N. = K.extension(z - 1) - sage: M is N + sage: N. = K.extension(z - 1) # optional - sage.libs.singular + sage: M is N # optional - sage.libs.singular False """ @@ -179,10 +179,10 @@ def create_object(self,version,key,**extra_args): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x - y^2) # indirect doctest - sage: y2 = y*1 - sage: M. = K.extension(x - y2^2) # indirect doctest - sage: L is M + sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.libs.singular + sage: y2 = y*1 # optional - sage.libs.singular + sage: M. = K.extension(x - y2^2) # indirect doctest # optional - sage.libs.singular + sage: L is M # optional - sage.libs.singular True """ from . import function_field @@ -206,5 +206,5 @@ def create_object(self,version,key,**extra_args): return function_field.FunctionField_char_zero(f, names) return function_field.FunctionField_polymod(f, names) -FunctionFieldExtension=FunctionFieldExtensionFactory( +FunctionFieldExtension = FunctionFieldExtensionFactory( "sage.rings.function_field.constructor.FunctionFieldExtension") diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 574ab1fc5b2..c5333ed7569 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -138,8 +138,8 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(b^2-a) - sage: b.__pari__() + sage: L. = K.extension(b^2 - a) # optional - sage.libs.singular + sage: b.__pari__() # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError: PARI does not support general function field elements. @@ -177,19 +177,19 @@ cdef class FunctionFieldElement(FieldElement): A rational function field:: sage: K. = FunctionField(QQ) - sage: t.matrix() + sage: t.matrix() # optional - sage.modules [t] - sage: (1/(t+1)).matrix() + sage: (1/(t+1)).matrix() # optional - sage.modules [1/(t + 1)] Now an example in a nontrivial extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y.matrix() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y.matrix() # optional - sage.libs.singular, sage.modules [ 0 1] [-4*x^3 x] - sage: y.matrix().charpoly('Z') + sage: y.matrix().charpoly('Z') # optional - sage.libs.singular, sage.modules Z^2 - x*Z + 4*x^3 An example in a relative extension, where neither function @@ -197,21 +197,21 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: M. = L[] - sage: Z. = L.extension(T^3 - y^2*T + x) - sage: alpha.matrix() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: M. = L[] # optional - sage.libs.singular + sage: Z. = L.extension(T^3 - y^2*T + x) # optional - sage.libs.singular + sage: alpha.matrix() # optional - sage.libs.singular, sage.modules [ 0 1 0] [ 0 0 1] [ -x x*y - 4*x^3 0] - sage: alpha.matrix(K) + sage: alpha.matrix(K) # optional - sage.libs.singular, sage.modules [ 0 0 1 0 0 0] [ 0 0 0 1 0 0] [ 0 0 0 0 1 0] [ 0 0 0 0 0 1] [ -x 0 -4*x^3 x 0 0] [ 0 -x -4*x^4 -4*x^3 + x^2 0 0] - sage: alpha.matrix(Z) + sage: alpha.matrix(Z) # optional - sage.libs.singular, sage.modules [alpha] We show that this matrix does indeed work as expected when making a @@ -219,13 +219,13 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: V, from_V, to_V = L.vector_space() - sage: y5 = to_V(y^5); y5 + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: V, from_V, to_V = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: y5 = to_V(y^5); y5 # optional - sage.libs.singular, sage.modules ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y4y = to_V(y^4) * y.matrix(); y4y + sage: y4y = to_V(y^4) * y.matrix(); y4y # optional - sage.libs.singular, sage.modules ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y5 == y4y + sage: y5 == y4y # optional - sage.libs.singular, sage.modules True """ # multiply each element of the vector space isomorphic to the parent @@ -247,8 +247,8 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y.trace() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y.trace() # optional - sage.libs.singular, sage.modules x """ return self.matrix().trace() @@ -260,18 +260,18 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y.norm() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y.norm() # optional - sage.libs.singular, sage.modules 4*x^3 The norm is relative:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] - sage: M. = L.extension(z^3 - y^2*z + x) - sage: z.norm() + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular + sage: z.norm() # optional - sage.libs.singular, sage.modules -x - sage: z.norm().parent() + sage: z.norm().parent() # optional - sage.libs.singular, sage.modules Function field in y defined by y^2 - x*y + 4*x^3 """ return self.matrix().determinant() @@ -320,13 +320,13 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] - sage: M. = L.extension(z^3 - y^2*z + x) - sage: x.characteristic_polynomial('W') + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular + sage: x.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules W - x - sage: y.characteristic_polynomial('W') + sage: y.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules W^2 - x*W + 4*x^3 - sage: z.characteristic_polynomial('W') + sage: z.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().characteristic_polynomial(*args, **kwds) @@ -341,13 +341,13 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] - sage: M. = L.extension(z^3 - y^2*z + x) - sage: x.minimal_polynomial('W') + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular + sage: x.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules W - x - sage: y.minimal_polynomial('W') + sage: y.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules W^2 - x*W + 4*x^3 - sage: z.minimal_polynomial('W') + sage: z.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().minimal_polynomial(*args, **kwds) @@ -361,16 +361,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y.is_integral() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y.is_integral() # optional - sage.libs.singular True - sage: (y/x).is_integral() + sage: (y/x).is_integral() # optional - sage.libs.singular, sage.modules True - sage: (y/x)^2 - (y/x) + 4*x + sage: (y/x)^2 - (y/x) + 4*x # optional - sage.libs.singular, sage.modules 0 - sage: (y/x^2).is_integral() + sage: (y/x^2).is_integral() # optional - sage.libs.singular, sage.modules False - sage: (y/x).minimal_polynomial('W') + sage: (y/x).minimal_polynomial('W') # optional - sage.libs.singular, sage.modules W^2 - W + 4*x """ R = self.parent().base_field().maximal_order() @@ -384,12 +384,12 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: f = 1 / t - sage: f.differential() + sage: f.differential() # optional - sage.modules (-1/t^2) d(t) sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari - sage: (y^3 + x).differential() # optional - sage.libs.pari + sage: (y^3 + x).differential() # optional - sage.libs.pari, sage.modules (((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3) d(x) TESTS: @@ -402,11 +402,11 @@ cdef class FunctionFieldElement(FieldElement): sage: R. = L[] # optional - sage.libs.pari sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: x.differential() # optional - sage.libs.pari + sage: x.differential() # optional - sage.libs.pari, sage.modules d(x) - sage: y.differential() # optional - sage.libs.pari + sage: y.differential() # optional - sage.libs.pari, sage.modules (16/x*y) d(x) - sage: z.differential() # optional - sage.libs.pari + sage: z.differential() # optional - sage.libs.pari, sage.modules (8/x*z) d(x) """ F = self.parent() @@ -424,12 +424,12 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: f = (t + 1) / (t^2 - 1/3) - sage: f.derivative() + sage: f.derivative() # optional - sage.modules (-t^2 - 2*t - 1/3)/(t^4 - 2/3*t^2 + 1/9) sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).derivative() # optional - sage.libs.pari + sage: (y^3 + x).derivative() # optional - sage.libs.pari, sage.modules ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 """ D = self.parent().derivation() @@ -449,16 +449,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) - sage: f = t^2 - sage: f.higher_derivative(2) + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: f = t^2 # optional - sage.libs.pari + sage: f.higher_derivative(2) # optional - sage.libs.pari, sage.modules 1 :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari + sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari, sage.modules 1/x^3*y + (x^6 + x^4 + x^3 + x^2 + x + 1)/x^5 """ D = self.parent().higher_derivation() @@ -473,7 +473,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor() # optional - sage.libs.pari + sage: f.divisor() # optional - sage.libs.pari, sage.modules 3*Place (1/x) - Place (x) - Place (x^2 + x + 1) @@ -482,7 +482,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: y.divisor() # optional - sage.libs.pari + sage: y.divisor() # optional - sage.libs.pari, sage.modules - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -503,14 +503,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_zeros() # optional - sage.libs.pari + sage: f.divisor_of_zeros() # optional - sage.libs.pari, sage.modules 3*Place (1/x) :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari + sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari, sage.modules 3*Place (x, x*y) """ if self.is_zero(): @@ -529,7 +529,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_poles() # optional - sage.libs.pari + sage: f.divisor_of_poles() # optional - sage.libs.pari, sage.modules Place (x) + Place (x^2 + x + 1) @@ -537,7 +537,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_poles() # optional - sage.libs.pari + sage: (x/y).divisor_of_poles() # optional - sage.libs.pari, sage.modules Place (1/x, 1/x*y) + 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -556,14 +556,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.zeros() # optional - sage.libs.pari + sage: f.zeros() # optional - sage.libs.pari, sage.modules [Place (1/x)] :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).zeros() # optional - sage.libs.pari + sage: (x/y).zeros() # optional - sage.libs.pari, sage.modules [Place (x, x*y)] """ return self.divisor_of_zeros().support() @@ -576,14 +576,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.poles() # optional - sage.libs.pari + sage: f.poles() # optional - sage.libs.pari, sage.modules [Place (x), Place (x^2 + x + 1)] :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).poles() # optional - sage.libs.pari + sage: (x/y).poles() # optional - sage.libs.pari, sage.modules [Place (1/x, 1/x*y), Place (x + 1, x*y)] """ return self.divisor_of_poles().support() @@ -600,17 +600,17 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_infinite()[0] # optional - sage.libs.pari - sage: y.valuation(p) # optional - sage.libs.pari + sage: p = L.places_infinite()[0] # optional - sage.libs.pari, sage.modules + sage: y.valuation(p) # optional - sage.libs.pari, sage.modules -1 :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: p = O.ideal(x-1).place() - sage: y.valuation(p) + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: p = O.ideal(x - 1).place() # optional - sage.libs.singular + sage: y.valuation(p) # optional - sage.libs.singular 0 """ prime = place.prime_ideal() @@ -723,8 +723,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: x*y + 1/x^3 + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: x*y + 1/x^3 # optional - sage.libs.singular x*y + 1/x^3 """ def __init__(self, parent, x, reduce=True): @@ -734,8 +734,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: TestSuite(x*y + 1/x^3).run() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: TestSuite(x*y + 1/x^3).run() # optional - sage.libs.singular """ FieldElement.__init__(self, parent) if reduce: @@ -750,10 +750,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(T^2 - x*T + 4*x^3) - sage: f = y/x^2 + x/(x^2+1); f + sage: L. = K.extension(T^2 - x*T + 4*x^3) # optional - sage.libs.singular + sage: f = y/x^2 + x/(x^2+1); f # optional - sage.libs.singular 1/x^2*y + x/(x^2 + 1) - sage: f.element() + sage: f.element() # optional - sage.libs.singular 1/x^2*y + x/(x^2 + 1) """ return self._x @@ -765,8 +765,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y._repr_() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y._repr_() # optional - sage.libs.singular 'y' """ return self._x._repr(name=self.parent().variable_name()) @@ -778,12 +778,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: bool(y) + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: bool(y) # optional - sage.libs.singular True - sage: bool(L(0)) + sage: bool(L(0)) # optional - sage.libs.singular False - sage: bool(L.coerce(L.polynomial())) + sage: bool(L.coerce(L.polynomial())) # optional - sage.libs.singular False """ return not not self._x @@ -795,8 +795,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 # optional - sage.libs.singular True """ return hash(self._x) @@ -808,10 +808,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: L(0) == 0 + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: L(0) == 0 # optional - sage.libs.singular True - sage: y != L(2) + sage: y != L(2) # optional - sage.libs.singular True """ cdef FunctionFieldElement left = self @@ -829,12 +829,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular (5*x + 5)*y + x/(x^3 + 1) - sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest + sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest # optional - sage.libs.singular True - sage: -y+y + sage: -y + y # optional - sage.libs.singular 0 """ cdef FunctionFieldElement res = self._new_c() @@ -852,10 +852,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular (-5*x - 1)*y + x/(x^3 + 1) - sage: y-y + sage: y - y # optional - sage.libs.singular 0 """ cdef FunctionFieldElement res = self._new_c() @@ -873,8 +873,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: y * (3*y + 5*x*y) # indirect doctest + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y * (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3 """ cdef FunctionFieldElement res = self._new_c() @@ -892,10 +892,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest # optional - sage.libs.singular 1 - sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest + sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: Cannot invert 0 @@ -909,10 +909,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: a = ~(2*y + 1/x); a # indirect doctest + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: a = ~(2*y + 1/x); a # indirect doctest # optional - sage.libs.singular (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a*(2*y + 1/x) + sage: a*(2*y + 1/x) # optional - sage.libs.singular 1 """ if self.is_zero(): @@ -930,12 +930,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: a = ~(2*y + 1/x); a + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: a = ~(2*y + 1/x); a # optional - sage.libs.singular (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a.list() + sage: a.list() # optional - sage.libs.singular [(1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16), -1/8*x^2/(x^5 + 1/8*x^2 + 1/16)] - sage: (x*y).list() + sage: (x*y).list() # optional - sage.libs.singular [0, x] """ return self._x.padded_list(self._parent.degree()) @@ -1140,16 +1140,16 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(7)) - sage: t.element() + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: t.element() # optional - sage.libs.pari t - sage: type(t.element()) + sage: type(t.element()) # optional - sage.libs.pari <... 'sage.rings.fraction_field_FpT.FpTElement'> - sage: K. = FunctionField(GF(131101)) - sage: t.element() + sage: K. = FunctionField(GF(131101)) # optional - sage.libs.pari + sage: t.element() # optional - sage.libs.pari t - sage: type(t.element()) + sage: type(t.element()) # optional - sage.libs.pari <... 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'> """ return self._x @@ -1544,13 +1544,13 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: K. = FunctionField(QQ) sage: f = (t+1) / (t^2 - 1/3) - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (t + 1) * (t^2 - 1/3)^-1 - sage: (7*f).factor() + sage: (7*f).factor() # optional - sage.libs.pari (7) * (t + 1) * (t^2 - 1/3)^-1 - sage: ((7*f).factor()).unit() + sage: ((7*f).factor()).unit() # optional - sage.libs.pari 7 - sage: (f^3).factor() + sage: (f^3).factor() # optional - sage.libs.pari (t + 1)^3 * (t^2 - 1/3)^-3 """ P = self.parent() diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index 9b891f4fa7b..6e9d88aee3c 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -84,7 +84,7 @@ def __init__(self, F, k_ext): sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) + sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) # optional - sage.libs.pari """ k = F.constant_base_field() F_base = F.base_field() @@ -120,10 +120,10 @@ def top(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: E = F.extension_constant_field(GF(2^3)) - sage: E.top() + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari + sage: E.top() # optional - sage.libs.pari Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return self._F_ext diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index baa7becf571..eeb27a6d825 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -24,31 +24,31 @@ simple arithmetic in it:: sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari, sage.libs.singular Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: y^2 # optional - sage.libs.pari + sage: y^2 # optional - sage.libs.pari, sage.libs.singular y^2 - sage: y^3 # optional - sage.libs.pari + sage: y^3 # optional - sage.libs.pari, sage.libs.singular 2*x*y + (x^4 + 1)/x - sage: a = 1/y; a # optional - sage.libs.pari + sage: a = 1/y; a # optional - sage.libs.pari, sage.libs.singular (x/(x^4 + 1))*y^2 + 3*x^2/(x^4 + 1) - sage: a * y # optional - sage.libs.pari + sage: a * y # optional - sage.libs.pari, sage.libs.singular 1 We next make an extension of the above function field, illustrating that arithmetic with a tower of three fields is fully supported:: sage: S. = L[] # optional - sage.libs.pari - sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari, sage.libs.singular + sage: M # optional - sage.libs.pari, sage.libs.singular Function field in t defined by t^2 + 4*x*y - sage: t^2 # optional - sage.libs.pari + sage: t^2 # optional - sage.libs.pari, sage.libs.singular x*y - sage: 1/t # optional - sage.libs.pari + sage: 1/t # optional - sage.libs.pari, sage.libs.singular ((1/(x^4 + 1))*y^2 + 3*x/(x^4 + 1))*t - sage: M.base_field() # optional - sage.libs.pari + sage: M.base_field() # optional - sage.libs.pari, sage.libs.singular Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: M.base_field().base_field() # optional - sage.libs.pari + sage: M.base_field().base_field() # optional - sage.libs.pari, sage.libs.singular Rational function field in x over Finite Field in a of size 5^2 It is also possible to construct function fields over an imperfect base field:: @@ -60,72 +60,72 @@ sage: J. = FunctionField(GF(5)); J # optional - sage.libs.pari Rational function field in x over Finite Field of size 5 sage: T. = J[] # optional - sage.libs.pari - sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari + sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari, sage.libs.singular Function field in v defined by v^5 + 4*x Function fields over the rational field are supported:: sage: F. = FunctionField(QQ) sage: R. = F[] - sage: L. = F.extension(Y^2 - x^8 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(x, y - 1) - sage: P = I.place() - sage: D = P.divisor() - sage: D.basis_function_space() + sage: L. = F.extension(Y^2 - x^8 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(x, y - 1) # optional - sage.libs.singular + sage: P = I.place() # optional - sage.libs.singular + sage: D = P.divisor() # optional - sage.libs.singular + sage: D.basis_function_space() # optional - sage.libs.singular [1] - sage: (2*D).basis_function_space() + sage: (2*D).basis_function_space() # optional - sage.libs.singular [1] - sage: (3*D).basis_function_space() + sage: (3*D).basis_function_space() # optional - sage.libs.singular [1] - sage: (4*D).basis_function_space() + sage: (4*D).basis_function_space() # optional - sage.libs.singular [1, 1/x^4*y + 1/x^4] sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor() + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: I.divisor() # optional - sage.libs.singular 2*Place (x, y, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, y, (1/(x^3 + x^2 + x))*y^2) sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I.divisor() + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: I.divisor() # optional - sage.libs.singular - Place (x, x*y) + Place (x^2 + 1, x*y) Function fields over the algebraic field are supported:: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.number_field - sage: O = L.maximal_order() # optional - sage.rings.number_field - sage: I = O.ideal(y) # optional - sage.rings.number_field - sage: I.divisor() # optional - sage.rings.number_field + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular, sage.rings.number_field + sage: O = L.maximal_order() # optional - sage.libs.singular, sage.rings.number_field + sage: I = O.ideal(y) # optional - sage.libs.singular, sage.rings.number_field + sage: I.divisor() # optional - sage.libs.singular, sage.rings.number_field Place (x - I, x*y) - Place (x, x*y) + Place (x + I, x*y) - sage: pl = I.divisor().support()[0] # optional - sage.rings.number_field - sage: m = L.completion(pl, prec=5) # optional - sage.rings.number_field - sage: m(x) # optional - sage.rings.number_field + sage: pl = I.divisor().support()[0] # optional - sage.libs.singular, sage.rings.number_field + sage: m = L.completion(pl, prec=5) # optional - sage.libs.singular, sage.rings.number_field + sage: m(x) # optional - sage.libs.singular, sage.rings.number_field I + s + O(s^5) - sage: m(y) # long time (4s) # optional - sage.rings.number_field + sage: m(y) # long time (4s) # optional - sage.libs.singular, sage.rings.number_field -2*s + (-4 - I)*s^2 + (-15 - 4*I)*s^3 + (-75 - 23*I)*s^4 + (-413 - 154*I)*s^5 + O(s^6) - sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.rings.number_field + sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.libs.singular, sage.rings.number_field O(s^5) TESTS:: - sage: TestSuite(J).run() + sage: TestSuite(J).run() # optional - sage.libs.pari sage: TestSuite(K).run(max_runs=256) # long time (10s) # optional - sage.rings.number_field - sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.rings.number_field + sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.libs.singular, sage.rings.number_field sage: TestSuite(M).run(max_runs=8) # long time (35s) sage: TestSuite(N).run(max_runs=8, skip = '_test_derivation') # long time (15s) - sage: TestSuite(O).run() # optional - sage.rings.number_field + sage: TestSuite(O).run() # optional - sage.libs.singular, sage.rings.number_field sage: TestSuite(R).run() - sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.pari + sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.singular, sage.libs.pari Global function fields ---------------------- @@ -329,8 +329,8 @@ def some_elements(self): :: sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L.some_elements() + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L.some_elements() # optional - sage.libs.singular [1, y, 1/x*y, @@ -386,8 +386,8 @@ def is_finite(self): sage: R. = FunctionField(QQ) sage: R.is_finite() False - sage: R. = FunctionField(GF(7)) - sage: R.is_finite() + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: R.is_finite() # optional - sage.libs.pari False """ return False @@ -429,18 +429,18 @@ def extension(self, f, names=None): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^5 - x^3 - 3*x + x*y) + sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular Function field in y defined by y^5 + x*y - x^3 - 3*x A nonintegral defining polynomial:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^3 + (1/t)*y + t^3/(t+1), 'z') + sage: K.extension(y^3 + (1/t)*y + t^3/(t+1), 'z') # optional - sage.libs.singular Function field in z defined by z^3 + 1/t*z + t^3/(t + 1) The defining polynomial need not be monic or integral:: - sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) + sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) """ from . import constructor @@ -465,29 +465,30 @@ def order_with_basis(self, basis, check=True): EXAMPLES:: - sage: K. = FunctionField(QQ); R. = K[]; L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: O = L.order_with_basis([1, y, y^2]); O + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: O = L.order_with_basis([1, y, y^2]); O # optional - sage.libs.singular Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.singular (1, y, y^2) Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it:: - sage: O = L.order_with_basis([1+y, y, y^2]); O + sage: O = L.order_with_basis([1+y, y, y^2]); O # optional - sage.libs.singular Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.singular (y + 1, y, y^2) The following error is raised when the module spanned by the basis is not closed under multiplication:: - sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O + sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: the module generated by basis (1, x*y + x^2, 2/3*y^2) must be closed under multiplication and this happens when the identity is not in the module spanned by the basis:: - sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2]) + sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2]) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: the identity element must be in the module spanned by basis (x, x*y + x^2, 2/3*y^2) @@ -508,20 +509,20 @@ def order(self, x, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: O = L.order(y); O + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: O = L.order(y); O # optional - sage.libs.singular, sage.modules Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.singular, sage.modules (1, y, y^2) - sage: Z = K.order(x); Z + sage: Z = K.order(x); Z # optional - sage.modules Order in Rational function field in x over Rational Field - sage: Z.basis() + sage: Z.basis() # optional - sage.modules (1,) Orders with multiple generators are not yet supported:: - sage: Z = K.order([x,x^2]); Z + sage: Z = K.order([x, x^2]); Z # optional - sage.modules Traceback (most recent call last): ... NotImplementedError @@ -553,24 +554,24 @@ def order_infinite_with_basis(self, basis, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: O = L.order_infinite_with_basis([1, 1/x*y, 1/x^2*y^2]); O + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: O = L.order_infinite_with_basis([1, 1/x*y, 1/x^2*y^2]); O # optional - sage.libs.singular Infinite order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.singular (1, 1/x*y, 1/x^2*y^2) Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1+1/x*y,1/x*y, 1/x^2*y^2]); O + sage: O = L.order_infinite_with_basis([1+1/x*y,1/x*y, 1/x^2*y^2]); O # optional - sage.libs.singular Infinite order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() + sage: O.basis() # optional - sage.libs.singular (1/x*y + 1, 1/x*y, 1/x^2*y^2) The following error is raised when the module spanned by the basis is not closed under multiplication:: - sage: O = L.order_infinite_with_basis([1,y, 1/x^2*y^2]); O + sage: O = L.order_infinite_with_basis([1,y, 1/x^2*y^2]); O # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2) must be closed under multiplication @@ -578,7 +579,7 @@ def order_infinite_with_basis(self, basis, check=True): and this happens when the identity is not in the module spanned by the basis:: - sage: O = L.order_infinite_with_basis([1/x,1/x*y, 1/x^2*y^2]) + sage: O = L.order_infinite_with_basis([1/x,1/x*y, 1/x^2*y^2]) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: the identity element must be in the module spanned by basis (1/x, 1/x*y, 1/x^2*y^2) @@ -599,17 +600,17 @@ def order_infinite(self, x, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: L.order_infinite(y) # todo: not implemented + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: L.order_infinite(y) # todo: not implemented # optional - sage.libs.singular, sage.modules - sage: Z = K.order(x); Z + sage: Z = K.order(x); Z # optional - sage.modules Order in Rational function field in x over Rational Field - sage: Z.basis() + sage: Z.basis() # optional - sage.modules (1,) Orders with multiple generators, not yet supported:: - sage: Z = K.order_infinite([x,x^2]); Z + sage: Z = K.order_infinite([x, x^2]); Z # optional - sage.modules Traceback (most recent call last): ... NotImplementedError @@ -635,14 +636,15 @@ def _coerce_map_from_(self, source): EXAMPLES:: - sage: K. = FunctionField(QQ); R. = K[]; L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: L.equation_order() + sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: L.equation_order() # optional - sage.libs.singular Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(L.equation_order()) + sage: L._coerce_map_from_(L.equation_order()) # optional - sage.libs.singular Conversion map: From: Order in Function field in y defined by y^3 + x^3 + 4*x + 1 To: Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari + sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari, sage.libs.singular sage: K. = FunctionField(QQ) sage: L. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field @@ -651,7 +653,7 @@ def _coerce_map_from_(self, source): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + 1) + sage: L. = K.extension(y^3 + 1) # optional - sage.libs.pari sage: K. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field sage: R. = K[] # optional - sage.rings.number_field sage: M. = K.extension(y^3 + 1) # optional - sage.rings.number_field @@ -660,9 +662,9 @@ def _coerce_map_from_(self, source): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(I^2 + 1) + sage: L. = K.extension(I^2 + 1) # optional - sage.libs.pari sage: M. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field - sage: M.has_coerce_map_from(L) # optional - sage.rings.number_field + sage: M.has_coerce_map_from(L) # optional - sage.libs.pari, sage.rings.number_field True Check that :trac:`31072` is fixed:: @@ -760,8 +762,8 @@ def _convert_map_from_(self, R): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) - sage: K(L(x)) # indirect doctest + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular + sage: K(L(x)) # indirect doctest # optional - sage.libs.singular x """ if isinstance(R, FunctionField_polymod): @@ -791,25 +793,25 @@ def _intermediate_fields(self, base): [Rational function field in x over Rational Field] sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: L._intermediate_fields(K) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L._intermediate_fields(K) # optional - sage.libs.singular [Function field in y defined by y^2 - x, Rational function field in x over Rational Field] - sage: R. = L[] - sage: M. = L.extension(z^2-y) - sage: M._intermediate_fields(L) + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M._intermediate_fields(L) # optional - sage.libs.singular [Function field in z defined by z^2 - y, Function field in y defined by y^2 - x] - sage: M._intermediate_fields(K) + sage: M._intermediate_fields(K) # optional - sage.libs.singular [Function field in z defined by z^2 - y, Function field in y defined by y^2 - x, Rational function field in x over Rational Field] TESTS:: - sage: K._intermediate_fields(M) + sage: K._intermediate_fields(M) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: field has not been constructed as a finite extension of base - sage: K._intermediate_fields(QQ) + sage: K._intermediate_fields(QQ) # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: base must be a function field @@ -836,13 +838,13 @@ def rational_function_field(self): Rational function field in x over Rational Field sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: L.rational_function_field() + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L.rational_function_field() # optional - sage.libs.singular Rational function field in x over Rational Field - sage: R. = L[] - sage: M. = L.extension(z^2-y) - sage: M.rational_function_field() + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.rational_function_field() # optional - sage.libs.singular Rational function field in x over Rational Field """ return self if isinstance(self, RationalFunctionField) else self.base_field().rational_function_field() @@ -1021,7 +1023,7 @@ def basis_of_holomorphic_differentials(self): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.basis_of_holomorphic_differentials() + sage: K.basis_of_holomorphic_differentials() # optional - sage.modules [] sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari @@ -1043,12 +1045,12 @@ def divisor_group(self): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: K.divisor_group() + sage: K.divisor_group() # optional - sage.modules Divisor group of Rational function field in t over Rational Field sage: _. = K[] - sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) - sage: L.divisor_group() + sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.singular + sage: L.divisor_group() # optional - sage.modules, sage.singular Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari @@ -1153,28 +1155,29 @@ def completion(self, place, name=None, prec=None, gen_name=None): 0 sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x) - sage: O = L.maximal_order() - sage: decomp = O.decomposition(K.maximal_order().ideal(x - 1)) - sage: pls = (decomp[0][0].place(), decomp[1][0].place()) - sage: m = L.completion(pls[0]); m + sage: L. = K.extension(Y^2 - x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: decomp = O.decomposition(K.maximal_order().ideal(x - 1)) # optional - sage.libs.singular + sage: pls = (decomp[0][0].place(), decomp[1][0].place()) # optional - sage.libs.singular + sage: m = L.completion(pls[0]); m # optional - sage.libs.singular Completion map: From: Function field in y defined by y^2 - x To: Laurent Series Ring in s over Rational Field - sage: xe = m(x) - sage: ye = m(y) - sage: ye^2 - xe == 0 + sage: xe = m(x) # optional - sage.libs.singular + sage: ye = m(y) # optional - sage.libs.singular + sage: ye^2 - xe == 0 # optional - sage.libs.singular True - sage: decomp2 = O.decomposition(K.maximal_order().ideal(x^2 + 1)) - sage: pls2 = decomp2[0][0].place() - sage: m = L.completion(pls2); m + sage: decomp2 = O.decomposition(K.maximal_order().ideal(x^2 + 1)) # optional - sage.libs.singular + sage: pls2 = decomp2[0][0].place() # optional - sage.libs.singular + sage: m = L.completion(pls2); m # optional - sage.libs.singular Completion map: From: Function field in y defined by y^2 - x - To: Laurent Series Ring in s over Number Field in a with defining polynomial x^4 + 2*x^2 + 4*x + 2 - sage: xe = m(x) - sage: ye = m(y) - sage: ye^2 - xe == 0 + To: Laurent Series Ring in s over + Number Field in a with defining polynomial x^4 + 2*x^2 + 4*x + 2 + sage: xe = m(x) # optional - sage.libs.singular + sage: ye = m(y) # optional - sage.libs.singular + sage: ye^2 - xe == 0 # optional - sage.libs.singular True """ from .maps import FunctionFieldCompletion @@ -1222,29 +1225,29 @@ class FunctionField_polymod(FunctionField): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x We next make a function field over the above nontrivial function field L:: - sage: S. = L[] - sage: M. = L.extension(z^2 + y*z + y); M + sage: S. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 + y*z + y); M # optional - sage.libs.singular Function field in z defined by z^2 + y*z + y - sage: 1/z + sage: 1/z # optional - sage.libs.singular ((-x/(x^4 + 1))*y^4 + 2*x^2/(x^4 + 1))*z - 1 - sage: z * (1/z) + sage: z * (1/z) # optional - sage.libs.singular 1 We drill down the tower of function fields:: - sage: M.base_field() + sage: M.base_field() # optional - sage.libs.singular Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: M.base_field().base_field() + sage: M.base_field().base_field() # optional - sage.libs.singular Rational function field in x over Rational Field - sage: M.base_field().base_field().constant_field() + sage: M.base_field().base_field().constant_field() # optional - sage.libs.singular Rational Field - sage: M.constant_base_field() + sage: M.constant_base_field() # optional - sage.libs.singular Rational Field .. WARNING:: @@ -1257,12 +1260,12 @@ class FunctionField_polymod(FunctionField): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x^2 - y^2) - sage: (y - x)*(y + x) + sage: L. = K.extension(x^2 - y^2) # optional - sage.libs.singular + sage: (y - x)*(y + x) # optional - sage.libs.singular 0 - sage: 1/(y - x) + sage: 1/(y - x) # optional - sage.libs.singular 1 - sage: y - x == 0; y + x == 0 + sage: y - x == 0; y + x == 0 # optional - sage.libs.singular False False """ @@ -1278,13 +1281,13 @@ def __init__(self, polynomial, names, category=None): We create an extension of a function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L + sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular Function field in y defined by y^5 + x*y - x^3 - 3*x - sage: TestSuite(L).run(max_runs=512) # long time (15s) + sage: TestSuite(L).run(max_runs=512) # long time (15s) # optional - sage.libs.singular We can set the variable name, which doesn't have to be y:: - sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L + sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular Function field in w defined by w^5 + x*w - x^3 - 3*x TESTS: @@ -1293,12 +1296,12 @@ def __init__(self, polynomial, names, category=None): sage: K. = FunctionField(QQ) sage: R. = QQ[] - sage: M. = K.extension(x^7-x-t) - sage: M(x) + sage: M. = K.extension(x^7 - x - t) # optional - sage.libs.singular + sage: M(x) # optional - sage.libs.singular z - sage: M('z') + sage: M('z') # optional - sage.libs.singular z - sage: M('x') + sage: M('x') # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: unable to evaluate 'x' in Fraction Field of Univariate @@ -1341,8 +1344,8 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y) - sage: hash(L) == hash(L.polynomial()) + sage: L = K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular + sage: hash(L) == hash(L.polynomial()) # optional - sage.libs.singular True """ return self._hash @@ -1358,8 +1361,8 @@ def _element_constructor_(self, x): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L._element_constructor_(L.polynomial_ring().gen()) + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L._element_constructor_(L.polynomial_ring().gen()) # optional - sage.libs.singular y """ if isinstance(x, FunctionFieldElement): @@ -1375,10 +1378,10 @@ def gen(self, n=0): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.gen() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.gen() # optional - sage.libs.singular y - sage: L.gen(1) + sage: L.gen(1) # optional - sage.libs.singular Traceback (most recent call last): ... IndexError: there is only one generator @@ -1395,8 +1398,8 @@ def ngens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.ngens() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.ngens() # optional - sage.libs.singular 1 """ return 1 @@ -1414,10 +1417,10 @@ def _to_base_field(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L._to_base_field(L(x)) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L._to_base_field(L(x)) # optional - sage.libs.singular x - sage: L._to_base_field(y) + sage: L._to_base_field(y) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: y is not an element of the base field @@ -1426,16 +1429,16 @@ def _to_base_field(self, f): Verify that :trac:`21872` has been resolved:: - sage: R. = L[] - sage: M. = L.extension(z^2 - y) + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M(1) in QQ + sage: M(1) in QQ # optional - sage.libs.singular True - sage: M(y) in L + sage: M(y) in L # optional - sage.libs.singular True - sage: M(x) in K + sage: M(x) in K # optional - sage.libs.singular True - sage: z in K + sage: z in K # optional - sage.libs.singular False """ K = self.base_field() @@ -1456,10 +1459,10 @@ def _to_constant_base_field(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L._to_constant_base_field(L(1)) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L._to_constant_base_field(L(1)) # optional - sage.libs.singular 1 - sage: L._to_constant_base_field(y) + sage: L._to_constant_base_field(y) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: y is not an element of the base field @@ -1468,9 +1471,9 @@ def _to_constant_base_field(self, f): Verify that :trac:`21872` has been resolved:: - sage: L(1) in QQ + sage: L(1) in QQ # optional - sage.libs.singular True - sage: y in QQ + sage: y in QQ # optional - sage.libs.singular False """ return self.base_field()._to_constant_base_field(self._to_base_field(f)) @@ -1498,38 +1501,39 @@ def monic_integral_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x); L + sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular Function field in y defined by x^2*y^5 - 1/x - sage: A, from_A, to_A = L.monic_integral_model('z') - sage: A + sage: A, from_A, to_A = L.monic_integral_model('z') # optional - sage.libs.singular + sage: A # optional - sage.libs.singular Function field in z defined by z^5 - x^12 - sage: from_A + sage: from_A # optional - sage.libs.singular Function Field morphism: From: Function field in z defined by z^5 - x^12 To: Function field in y defined by x^2*y^5 - 1/x Defn: z |--> x^3*y x |--> x - sage: to_A + sage: to_A # optional - sage.libs.singular Function Field morphism: From: Function field in y defined by x^2*y^5 - 1/x To: Function field in z defined by z^5 - x^12 Defn: y |--> 1/x^3*z x |--> x - sage: to_A(y) + sage: to_A(y) # optional - sage.libs.singular 1/x^3*z - sage: from_A(to_A(y)) + sage: from_A(to_A(y)) # optional - sage.libs.singular y - sage: from_A(to_A(1/y)) + sage: from_A(to_A(1/y)) # optional - sage.libs.singular x^3*y^4 - sage: from_A(to_A(1/y)) == 1/y + sage: from_A(to_A(1/y)) == 1/y # optional - sage.libs.singular True This also works for towers of function fields:: - sage: R. = L[] - sage: M. = L.extension(z^2*y - 1/x) - sage: M.monic_integral_model() - (Function field in z_ defined by z_^10 - x^18, Function Field morphism: + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2*y - 1/x) # optional - sage.libs.singular + sage: M.monic_integral_model() # optional - sage.libs.singular + (Function field in z_ defined by z_^10 - x^18, + Function Field morphism: From: Function field in z_ defined by z_^10 - x^18 To: Function field in z defined by y*z^2 - 1/x Defn: z_ |--> x^2*z @@ -1547,9 +1551,10 @@ def monic_integral_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: L.monic_integral_model() - (Function field in y defined by y^2 - x, Function Field endomorphism of Function field in y defined by y^2 - x + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L.monic_integral_model() # optional - sage.libs.singular + (Function field in y defined by y^2 - x, + Function Field endomorphism of Function field in y defined by y^2 - x Defn: y |--> y x |--> x, Function Field endomorphism of Function field in y defined by y^2 - x Defn: y |--> y @@ -1557,8 +1562,9 @@ def monic_integral_model(self, names=None): unless ``names`` does not match with the current names:: - sage: L.monic_integral_model(names=('yy','xx')) - (Function field in yy defined by yy^2 - xx, Function Field morphism: + sage: L.monic_integral_model(names=('yy','xx')) # optional - sage.libs.singular + (Function field in yy defined by yy^2 - xx, + Function Field morphism: From: Function field in yy defined by yy^2 - xx To: Function field in y defined by y^2 - x Defn: yy |--> y @@ -1613,14 +1619,14 @@ def _make_monic_integral(self, f): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x) - sage: g, d = L._make_monic_integral(L.polynomial()); g,d + sage: L. = K.extension(x^2*y^5 - 1/x) # optional - sage.libs.singular + sage: g, d = L._make_monic_integral(L.polynomial()); g,d # optional - sage.libs.singular (y^5 - x^12, x^3) - sage: (y*d).is_integral() + sage: (y*d).is_integral() # optional - sage.libs.singular True - sage: g.is_monic() + sage: g.is_monic() # optional - sage.libs.singular True - sage: g(y*d) + sage: g(y*d) # optional - sage.libs.singular 0 """ R = f.base_ring() @@ -1665,13 +1671,13 @@ def constant_base_field(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.constant_base_field() + sage: L.constant_base_field() # optional - sage.libs.singular Rational Field - sage: S. = L[] - sage: M. = L.extension(z^2 - y) - sage: M.constant_base_field() + sage: S. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.constant_base_field() # optional - sage.libs.singular Rational Field """ return self.base_field().constant_base_field() @@ -1690,23 +1696,23 @@ def degree(self, base=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.degree() + sage: L.degree() # optional - sage.libs.singular 5 - sage: L.degree(L) + sage: L.degree(L) # optional - sage.libs.singular 1 - sage: R. = L[] - sage: M. = L.extension(z^2 - y) - sage: M.degree(L) + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.degree(L) # optional - sage.libs.singular 2 - sage: M.degree(K) + sage: M.degree(K) # optional - sage.libs.singular 10 TESTS:: - sage: L.degree(M) + sage: L.degree(M) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: base must be the rational function field itself @@ -1726,8 +1732,8 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L._repr_() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L._repr_() # optional - sage.libs.singular 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' """ return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial) @@ -1741,8 +1747,8 @@ def base_field(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.base_field() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.base_field() # optional - sage.libs.singular Rational function field in x over Rational Field """ return self._base_field @@ -1755,8 +1761,8 @@ def random_element(self, *args, **kwds): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x)) - sage: L.random_element() # random + sage: L. = K.extension(y^2 - (x^2 + x)) # optional - sage.libs.singular + sage: L.random_element() # random # optional - sage.libs.singular ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95) """ @@ -1771,8 +1777,8 @@ def polynomial(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.polynomial() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.polynomial() # optional - sage.libs.singular y^5 - 2*x*y + (-x^4 - 1)/x """ return self._polynomial @@ -1832,8 +1838,8 @@ def polynomial_ring(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.polynomial_ring() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.polynomial_ring() # optional - sage.libs.singular Univariate Polynomial Ring in y over Rational function field in x over Rational Field """ return self._ring @@ -1872,53 +1878,53 @@ def free_module(self, base=None, basis=None, map=True): We define a function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x We get the vector spaces, and maps back and forth:: - sage: V, from_V, to_V = L.free_module() - sage: V + sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular, sage.modules + sage: V # optional - sage.libs.singular, sage.modules Vector space of dimension 5 over Rational function field in x over Rational Field - sage: from_V + sage: from_V # optional - sage.libs.singular, sage.modules Isomorphism: From: Vector space of dimension 5 over Rational function field in x over Rational Field To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: to_V + sage: to_V # optional - sage.libs.singular, sage.modules Isomorphism: From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Vector space of dimension 5 over Rational function field in x over Rational Field We convert an element of the vector space back to the function field:: - sage: from_V(V.1) + sage: from_V(V.1) # optional - sage.libs.singular, sage.modules y We define an interesting element of the function field:: - sage: a = 1/L.0; a + sage: a = 1/L.0; a # optional - sage.libs.singular, sage.modules (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1) We convert it to the vector space, and get a vector over the base field:: - sage: to_V(a) + sage: to_V(a) # optional - sage.libs.singular, sage.modules (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1)) We convert to and back, and get the same element:: - sage: from_V(to_V(a)) == a + sage: from_V(to_V(a)) == a # optional - sage.libs.singular, sage.modules True In the other direction:: - sage: v = x*V.0 + (1/x)*V.1 - sage: to_V(from_V(v)) == v + sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular, sage.modules + sage: to_V(from_V(v)) == v # optional - sage.libs.singular, sage.modules True And we show how it works over an extension of an extension field:: - sage: R2. = L[]; M. = L.extension(z^2 -y) - sage: M.free_module() + sage: R2. = L[]; M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.free_module() # optional - sage.libs.singular, sage.modules (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism: From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Function field in z defined by z^2 - y, Isomorphism: @@ -1927,7 +1933,7 @@ def free_module(self, base=None, basis=None, map=True): We can also get the vector space of ``M`` over ``K``:: - sage: M.free_module(K) + sage: M.free_module(K) # optional - sage.libs.singular, sage.modules (Vector space of dimension 10 over Rational function field in x over Rational Field, Isomorphism: From: Vector space of dimension 10 over Rational function field in x over Rational Field To: Function field in z defined by z^2 - y, Isomorphism: @@ -1955,8 +1961,8 @@ def maximal_order(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.maximal_order() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.maximal_order() # optional - sage.libs.singular Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x """ from .order import FunctionFieldMaximalOrder_polymod @@ -1969,8 +1975,8 @@ def maximal_order_infinite(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: L.maximal_order_infinite() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.maximal_order_infinite() # optional - sage.libs.singular Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari @@ -2014,19 +2020,19 @@ def equation_order(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: O = L.equation_order() - sage: O.basis() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.basis() # optional - sage.libs.singular (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4) We try an example, in which the defining polynomial is not monic and is not integral:: - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x); L + sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular + sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular Function field in y defined by x^2*y^5 - 1/x - sage: O = L.equation_order() - sage: O.basis() + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.basis() # optional - sage.libs.singular (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4) """ d = self._make_monic_integral(self.polynomial())[1] @@ -2051,40 +2057,40 @@ def hom(self, im_gens, base_morphism=None): We create a rational function field, and a quadratic extension of it:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular We make the field automorphism that sends y to -y:: - sage: f = L.hom(-y); f + sage: f = L.hom(-y); f # optional - sage.libs.singular Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 Defn: y |--> -y Evaluation works:: - sage: f(y*x - 1/x) + sage: f(y*x - 1/x) # optional - sage.libs.singular -x*y - 1/x We try to define an invalid morphism:: - sage: f = L.hom(y+1) + sage: f = L.hom(y + 1) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: invalid morphism We make a morphism of the base rational function field:: - sage: phi = K.hom(x+1); phi + sage: phi = K.hom(x + 1); phi # optional - sage.libs.singular Function Field endomorphism of Rational function field in x over Rational Field Defn: x |--> x + 1 - sage: phi(x^3 - 3) + sage: phi(x^3 - 3) # optional - sage.libs.singular x^3 + 3*x^2 + 3*x - 2 - sage: (x+1)^3-3 + sage: (x+1)^3 - 3 # optional - sage.libs.singular x^3 + 3*x^2 + 3*x - 2 We make a morphism by specifying where the generators and the base generators go:: - sage: L.hom([-y, x]) + sage: L.hom([-y, x]) # optional - sage.libs.singular Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 Defn: y |--> -y x |--> x @@ -2092,8 +2098,8 @@ def hom(self, im_gens, base_morphism=None): You can also specify a morphism on the base:: sage: R1. = K[] - sage: L1. = K.extension(q^2 - (x+1)^3 - 1) - sage: L.hom(q, base_morphism=phi) + sage: L1. = K.extension(q^2 - (x+1)^3 - 1) # optional - sage.libs.singular + sage: L.hom(q, base_morphism=phi) # optional - sage.libs.singular Function Field morphism: From: Function field in y defined by y^2 - x^3 - 1 To: Function field in q defined by q^2 - x^3 - 3*x^2 - 3*x - 2 @@ -2103,11 +2109,11 @@ def hom(self, im_gens, base_morphism=None): We make another extension of a rational function field:: sage: K2. = FunctionField(QQ); R2. = K2[] - sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) + sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) # optional - sage.libs.singular We define a morphism, by giving the images of generators:: - sage: f = L.hom([4*w, t+1]); f + sage: f = L.hom([4*w, t + 1]); f # optional - sage.libs.singular Function Field morphism: From: Function field in y defined by y^2 - x^3 - 1 To: Function field in w defined by 16*w^2 - t^3 - 3*t^2 - 3*t - 2 @@ -2116,19 +2122,19 @@ def hom(self, im_gens, base_morphism=None): Evaluation works, as expected:: - sage: f(y+x) + sage: f(y+x) # optional - sage.libs.singular 4*w + t + 1 - sage: f(x*y + x/(x^2+1)) + sage: f(x*y + x/(x^2+1)) # optional - sage.libs.singular (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2) We make another extension of a rational function field:: sage: K3. = FunctionField(QQ); R3. = K3[] - sage: L3. = K3.extension(yy^2 - xx^3 - 1) + sage: L3. = K3.extension(yy^2 - xx^3 - 1) # optional - sage.libs.singular This is the function field L with the generators exchanged. We define a morphism to L:: - sage: g = L3.hom([x,y]); g + sage: g = L3.hom([x,y]); g # optional - sage.libs.singular Function Field morphism: From: Function field in xx defined by -xx^3 + yy^2 - 1 To: Function field in y defined by y^2 - x^3 - 1 @@ -2163,8 +2169,8 @@ def genus(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) - sage: L.genus() + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.genus() # optional - sage.libs.singular 3 """ # Unfortunately Singular can not compute the genus with the @@ -2220,10 +2226,10 @@ def _simple_model(self, name='v'): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: R. = L[] - sage: M. = L.extension(z^2-y) - sage: M._simple_model() + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M._simple_model() # optional - sage.libs.singular (Function field in v defined by v^4 - x, Function Field morphism: From: Function field in v defined by v^4 - x @@ -2349,13 +2355,13 @@ def simple_model(self, name=None): A tower of four function fields:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(z^2-x); R. = L[] - sage: M. = L.extension(u^2-z); R. = M[] - sage: N. = M.extension(v^2-u) + sage: L. = K.extension(z^2 - x); R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(u^2 - z); R. = M[] # optional - sage.libs.singular + sage: N. = M.extension(v^2 - u) # optional - sage.libs.singular The fields N and M as simple extensions of K:: - sage: N.simple_model() + sage: N.simple_model() # optional - sage.libs.singular (Function field in v defined by v^8 - x, Function Field morphism: From: Function field in v defined by v^8 - x @@ -2368,7 +2374,7 @@ def simple_model(self, name=None): u |--> v^2 z |--> v^4 x |--> x) - sage: M.simple_model() + sage: M.simple_model() # optional - sage.libs.singular (Function field in u defined by u^4 - x, Function Field morphism: From: Function field in u defined by u^4 - x @@ -2384,7 +2390,7 @@ def simple_model(self, name=None): An optional parameter ``name`` can be used to set the name of the generator of the simple extension:: - sage: M.simple_model(name='t') + sage: M.simple_model(name='t') # optional - sage.libs.singular (Function field in t defined by t^4 - x, Function Field morphism: From: Function field in t defined by t^4 - x To: Function field in u defined by u^2 - z @@ -2474,16 +2480,16 @@ def primitive_element(self): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2-x) - sage: R. = L[] - sage: M. = L.extension(z^2-y) - sage: R. = L[] - sage: N. = L.extension(z^2-x-1) - sage: N.primitive_element() + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: N. = L.extension(z^2 - x - 1) # optional - sage.libs.singular + sage: N.primitive_element() # optional - sage.libs.singular u + y - sage: M.primitive_element() + sage: M.primitive_element() # optional - sage.libs.singular z - sage: L.primitive_element() + sage: L.primitive_element() # optional - sage.libs.singular y This also works for inseparable extensions:: @@ -2596,8 +2602,8 @@ def separable_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x^3) - sage: L.separable_model() + sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.singular + sage: L.separable_model() # optional - sage.libs.singular (Function field in y defined by y^2 - x^3, Function Field endomorphism of Function field in y defined by y^2 - x^3 Defn: y |--> y @@ -2729,11 +2735,11 @@ def change_variable_name(self, name): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: R. = L[] - sage: M. = L.extension(z^2 - y) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.change_variable_name('zz') + sage: M.change_variable_name('zz') # optional - sage.libs.singular (Function field in zz defined by zz^2 - y, Function Field morphism: From: Function field in zz defined by zz^2 - y @@ -2747,7 +2753,7 @@ def change_variable_name(self, name): Defn: z |--> zz y |--> y x |--> x) - sage: M.change_variable_name(('zz','yy')) + sage: M.change_variable_name(('zz','yy')) # optional - sage.libs.singular (Function field in zz defined by zz^2 - yy, Function Field morphism: From: Function field in zz defined by zz^2 - yy To: Function field in z defined by z^2 - y @@ -2759,7 +2765,7 @@ def change_variable_name(self, name): Defn: z |--> zz y |--> yy x |--> x) - sage: M.change_variable_name(('zz','yy','xx')) + sage: M.change_variable_name(('zz','yy','xx')) # optional - sage.libs.singular (Function field in zz defined by zz^2 - yy, Function Field morphism: From: Function field in zz defined by zz^2 - yy @@ -2877,19 +2883,19 @@ def places_above(self, p): True sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = K.maximal_order() - sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = K.maximal_order() # optional - sage.libs.singular + sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] # optional - sage.libs.singular + sage: all(q.place_below() == p # optional - sage.libs.singular ....: for p in pls for q in F.places_above(p)) True sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.rings.number_field - sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.rings.number_field + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular, sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular, sage.rings.number_field + sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular, sage.rings.number_field ....: for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p # long time (4s) # optional - sage.rings.number_field + sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular, sage.rings.number_field ....: for p in pls for q in F.places_above(p)) True """ @@ -3043,10 +3049,10 @@ class FunctionField_char_zero(FunctionField_simple): EXAMPLES:: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular + sage: L # optional - sage.libs.singular Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) - sage: L.characteristic() + sage: L.characteristic() # optional - sage.libs.singular 0 """ @cached_method @@ -3062,8 +3068,8 @@ def higher_derivation(self): EXAMPLES:: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) - sage: L.higher_derivation() + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular + sage: L.higher_derivation() # optional - sage.libs.singular, sage.modules Higher derivation map: From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) @@ -3147,7 +3153,7 @@ def higher_derivation(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.higher_derivation() # optional - sage.libs.pari + sage: L.higher_derivation() # optional - sage.libs.pari, sage.modules Higher derivation map: From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) @@ -3484,12 +3490,12 @@ def _singular_normal(ideal): sage: from sage.rings.function_field.function_field import _singular_normal sage: R. = QQ[] - sage: f = (x^2-y^3) * x - sage: _singular_normal(ideal(f)) + sage: f = (x^2 - y^3) * x + sage: _singular_normal(ideal(f)) # optional - sage.libs.singular [[x, y], [1]] - sage: f = (y^2-x) - sage: _singular_normal(ideal(f)) + sage: f = y^2 - x + sage: _singular_normal(ideal(f)) # optional - sage.libs.singular [[1]] """ from sage.libs.singular.function import singular_function, lib @@ -3630,8 +3636,8 @@ def equation_order(self): Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) - sage: F.equation_order() + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: F.equation_order() # optional - sage.libs.singular Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ from .order import FunctionFieldOrder_basis @@ -3683,8 +3689,8 @@ def equation_order_infinite(self): Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: F.equation_order_infinite() + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: F.equation_order_infinite() # optional - sage.libs.singular Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ from .order import FunctionFieldOrderInfinite_basis @@ -3774,8 +3780,8 @@ class RationalFunctionField(FunctionField): sage: R. = FunctionField(QQ) sage: L. = R[] - sage: F. = R.extension(y^2 - (x^2+1)) - sage: (y/x).divisor() + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular + sage: (y/x).divisor() # optional - sage.libs.singular, sage.modules - Place (x, y - 1) - Place (x, y + 1) + Place (x^2 + 1, y) @@ -3784,15 +3790,15 @@ class RationalFunctionField(FunctionField): sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field sage: R. = FunctionField(NF) # optional - sage.rings.number_field sage: L. = R[] # optional - sage.rings.number_field - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.rings.number_field + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular, sage.modules, sage.rings.number_field - sage: (x/y*x.differential()).divisor() # optional - sage.rings.number_field + sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular, sage.modules, sage.rings.number_field -2*Place (1/x, 1/x*y - 1) - 2*Place (1/x, 1/x*y + 1) + Place (x, y - 1) + Place (x, y + 1) - sage: (x/y).divisor() # optional - sage.rings.number_field + sage: (x/y).divisor() # optional - sage.libs.singular, sage.modules, sage.rings.number_field - Place (x - i, y) + Place (x, y - 1) + Place (x, y + 1) @@ -3924,8 +3930,8 @@ def _element_constructor_(self, x): Some indirect test of conversion:: sage: S. = K[] - sage: I = S*[x^2 - y^2, y-t] - sage: I.groebner_basis() + sage: I = S * [x^2 - y^2, y - t] # optional - sage.libs.singular + sage: I.groebner_basis() # optional - sage.libs.singular [x^2 - t^2, y - t] """ @@ -4040,9 +4046,9 @@ def _factor_univariate_polynomial(self, f, proof=None): sage: R. = FunctionField(QQ) sage: S. = R[] sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) - sage: f.factor() # indirect doctest + sage: f.factor() # indirect doctest # optional - sage.libs.singular (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2) - sage: f.factor().prod() == f + sage: f.factor().prod() == f # optional - sage.libs.singular True We do a factorization over a finite prime field:: @@ -4123,18 +4129,18 @@ def extension(self, f, names=None): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^5 - x^3 - 3*x + x*y) + sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular Function field in y defined by y^5 + x*y - x^3 - 3*x A nonintegral defining polynomial:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) + sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular Function field in y defined by y^3 + 1/t*y + t^3/(t + 1) The defining polynomial need not be monic or integral:: - sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) + sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) """ from . import constructor diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index f7348440bbf..fddb2e6dd4f 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -33,8 +33,8 @@ sage: v = K.valuation(x - 1); v (x - 1)-adic valuation sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: w = v.extensions(L); w + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: w = v.extensions(L); w # optional - sage.libs.singular [[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation, [ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation] @@ -57,9 +57,9 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(x - 1) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: ws = v.extensions(L) - sage: for w in ws: TestSuite(w).run(max_runs=100) # long time + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: ws = v.extensions(L) # optional - sage.libs.singular + sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # optional - sage.libs.singular Run test suite for valuations that do not correspond to a classical place:: @@ -88,9 +88,9 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(1/x) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) - sage: w = v.extensions(L) - sage: TestSuite(w).run() # long time + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular + sage: w = v.extensions(L) # optional - sage.libs.singular + sage: TestSuite(w).run() # long time # optional - sage.libs.singular Run test suite for a valuation with `v(1/x) > 0` which does not come from a classical valuation of the infinite place:: @@ -107,7 +107,7 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(x^2 + 1) sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: ws = v.extensions(L) + sage: ws = v.extensions(L) # optional - sage.libs.singular sage: for w in ws: TestSuite(w).run(max_runs=100) # long time Run test suite for a finite place with residual degree and ramification:: @@ -123,8 +123,8 @@ sage: R. = K[] sage: L. = K.extension(y^2 - (x^2 + x + 1)) sage: v = K.valuation(x - 1) - sage: w = v.extension(L) - sage: TestSuite(w).run() # long time + sage: w = v.extension(L) # optional - sage.libs.singular + sage: TestSuite(w).run() # long time # optional - sage.libs.singular Run test suite for a valuation which sends an element to `-\infty`:: @@ -306,9 +306,9 @@ def create_key_and_extra_args_from_valuation(self, domain, valuation): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) - sage: v = K.valuation(x) - sage: v.extensions(L) + sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) # optional - sage.libs.singular + sage: v = K.valuation(x) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular [[ (x)-adic valuation, v(y) = 1 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y), [ (x)-adic valuation, v(y) = 1/2 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)] @@ -353,9 +353,9 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari, sage.libs.singular + sage: v = K.valuation(1/x) # optional - sage.libs.pari, sage.libs.singular + sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari, sage.libs.singular """ from sage.categories.function_fields import FunctionFields @@ -492,8 +492,8 @@ def extensions(self, L): sage: K. = FunctionField(QQ) sage: v = K.valuation(x) sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: v.extensions(L) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular [(x)-adic valuation] TESTS: @@ -502,8 +502,8 @@ def extensions(self, L): sage: v = K.valuation(1/x) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) - sage: sorted(v.extensions(L), key=str) + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular + sage: sorted(v.extensions(L), key=str) # optional - sage.libs.singular [[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation, [ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation] @@ -530,8 +530,8 @@ def extensions(self, L): sage: v = K.valuation(v) sage: R. = K[] - sage: L. = K.extension(y^3 - x^4 - 1) - sage: v.extensions(L) + sage: L. = K.extension(y^3 - x^4 - 1) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular [2-adic valuation] Test that this works in towers:: @@ -601,15 +601,15 @@ def element_with_valuation(self, s): EXAMPLES:: - sage: K. = NumberField(x^3+6) - sage: v = K.valuation(2) - sage: R. = K[] - sage: w = GaussValuation(R, v).augmentation(x, 1/123) - sage: K. = FunctionField(K) - sage: w = w.extension(K) - sage: w.element_with_valuation(122/123) + sage: K. = NumberField(x^3+6) # optional - sage.rings.number_field + sage: v = K.valuation(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: w = GaussValuation(R, v).augmentation(x, 1/123) # optional - sage.rings.number_field + sage: K. = FunctionField(K) # optional - sage.rings.number_field + sage: w = w.extension(K) # optional - sage.rings.number_field + sage: w.element_with_valuation(122/123) # optional - sage.rings.number_field 2/x - sage: w.element_with_valuation(1) + sage: w.element_with_valuation(1) # optional - sage.rings.number_field 2 """ @@ -1077,8 +1077,8 @@ def residue_ring(self): Rational function field in x over Finite Field of size 2 sage: R. = K[] - sage: L. = K.extension(y^2 + 2*x) - sage: w.extension(L).residue_ring() + sage: L. = K.extension(y^2 + 2*x) # optional - sage.libs.singular + sage: w.extension(L).residue_ring() # optional - sage.libs.singular Function field in u2 defined by u2^2 + x TESTS: @@ -1109,9 +1109,9 @@ class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, Discret sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) - sage: v = K.valuation(x - 1) # indirect doctest - sage: w = v.extension(L); w + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L); w # optional - sage.libs.singular (x - 1)-adic valuation """ @@ -1121,11 +1121,11 @@ def __init__(self, parent, approximant, G, approximants): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) - sage: v = K.valuation(x - 1) # indirect doctest - sage: w = v.extension(L) + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular sage: from sage.rings.function_field.function_field_valuation import FunctionFieldFromLimitValuation - sage: isinstance(w, FunctionFieldFromLimitValuation) + sage: isinstance(w, FunctionFieldFromLimitValuation) # optional - sage.libs.singular True """ @@ -1140,10 +1140,10 @@ def _to_base_domain(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) - sage: v = K.valuation(x - 1) # indirect doctest - sage: w = v.extension(L) - sage: w._to_base_domain(y).parent() + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular + sage: w._to_base_domain(y).parent() # optional - sage.libs.singular Univariate Polynomial Ring in y over Rational function field in x over Rational Field """ @@ -1157,10 +1157,10 @@ def scale(self, scalar): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) - sage: v = K.valuation(x - 1) # indirect doctest - sage: w = v.extension(L) - sage: 3*w + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular + sage: 3*w # optional - sage.libs.singular 3 * (x - 1)-adic valuation """ @@ -1279,10 +1279,10 @@ def is_discrete_valuation(self): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x^4 - 1) - sage: v = K.valuation(1/x) - sage: w0,w1 = v.extensions(L) - sage: w0.is_discrete_valuation() + sage: L. = K.extension(y^2 - x^4 - 1) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w0,w1 = v.extensions(L) # optional - sage.libs.pari + sage: w0.is_discrete_valuation() # optional - sage.libs.pari True """ @@ -1451,9 +1451,9 @@ def _repr_(self): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/x^2 - 1) - sage: v = K.valuation(1/x) - sage: w = v.extensions(L); w + sage: L. = K.extension(y^2 - 1/x^2 - 1) # optional - sage.libs.singular + sage: v = K.valuation(1/x) # optional - sage.libs.singular + sage: w = v.extensions(L); w # optional - sage.libs.singular [[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation, [ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation] diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 44ce467ebf0..dd375fe79cd 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -26,11 +26,11 @@ Ideals in the equation order of an extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y); I + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y); I # optional - sage.libs.singular Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^2 + sage: I^2 # optional - sage.libs.singular Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 Ideals in the maximal order of a global function field:: @@ -167,9 +167,9 @@ def _repr_(self): Ideal (1/(x + 1)) of Maximal order of Rational function field in x over Rational Field sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: O.ideal(x^2 + 1) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.ideal(x^2 + 1) # optional - sage.libs.pari Ideal (x^2 + 1) of Order in Function field in y defined by y^2 - x^3 - 1 sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari @@ -296,10 +296,10 @@ def base_ring(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(x^2 + 1) - sage: I.base_ring() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular + sage: I.base_ring() # optional - sage.libs.singular Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring() @@ -416,17 +416,17 @@ def factor(self): of Function field in y defined by y^3 + x^6 + x^4 + x^2) sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: I == I.factor().prod() + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: I == I.factor().prod() # optional - sage.libs.singular True sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: I == I.factor().prod() + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: I == I.factor().prod() # optional - sage.libs.singular True """ @@ -737,8 +737,8 @@ def is_prime(self): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x^3+x^2) - sage: [f.is_prime() for f,m in I.factor()] + sage: I = O.ideal(x^3 + x^2) + sage: [f.is_prime() for f,m in I.factor()] # optional - sage.libs.pari [True, True] """ return self._gen.denominator() == 1 and self._gen.numerator().is_prime() @@ -753,13 +753,13 @@ def module(self): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() sage: I = O.ideal(x^3+x^2) - sage: I.module() + sage: I.module() # optional - sage.modules Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Rational Field Echelon basis matrix: [x^3 + x^2] sage: J = 0*I - sage: J.module() + sage: J.module() # optional - sage.modules Free module of degree 1 and rank 0 over Maximal order of Rational function field in x over Rational Field Echelon basis matrix: @@ -824,7 +824,7 @@ def valuation(self, ideal): sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: I = O.ideal(x^2*(x^2+x+1)^3) - sage: [f.valuation(I) for f,_ in I.factor()] + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari [2, 3] """ if not self.is_prime(): @@ -893,12 +893,12 @@ class FunctionFieldIdeal_module(FunctionFieldIdeal, Ideal_generic): An ideal in an extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: I + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: I # optional - sage.libs.singular Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^2 + sage: I^2 # optional - sage.libs.singular Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ def __init__(self, ring, module): @@ -908,10 +908,10 @@ def __init__(self, ring, module): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: TestSuite(I).run() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: TestSuite(I).run() # optional - sage.libs.singular """ FunctionFieldIdeal.__init__(self, ring) @@ -931,15 +931,15 @@ def __contains__(self, x): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y); I + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y); I # optional - sage.libs.singular Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: y in I + sage: y in I # optional - sage.libs.singular True - sage: y/x in I + sage: y/x in I # optional - sage.libs.singular False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.singular False """ return self._structure[2](x) in self._module @@ -951,10 +951,10 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: d = {I: 1} # indirect doctest + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: d = {I: 1} # indirect doctest # optional - sage.libs.singular """ return hash((self._ring,self._module)) @@ -965,18 +965,18 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(x, y); J = O.ideal(y^2 - 2) - sage: I + J == J + I # indirect test + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(x, y); J = O.ideal(y^2 - 2) # optional - sage.libs.singular + sage: I + J == J + I # indirect test # optional - sage.libs.singular True - sage: I + I == I # indirect doctest + sage: I + I == I # indirect doctest # optional - sage.libs.singular True - sage: I == J + sage: I == J # optional - sage.libs.singular False - sage: I < J + sage: I < J # optional - sage.libs.singular True - sage: J < I + sage: J < I # optional - sage.libs.singular False """ return richcmp(self.module().basis(), other.module().basis(), op) @@ -996,20 +996,20 @@ def module(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order(); O + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order(); O # optional - sage.libs.singular Order in Function field in y defined by y^2 - x^3 - 1 - sage: I = O.ideal(x^2 + 1) - sage: I.gens() + sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular + sage: I.gens() # optional - sage.libs.singular (x^2 + 1, (x^2 + 1)*y) - sage: I.module() + sage: I.module() # optional - sage.libs.singular Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Rational Field Echelon basis matrix: [x^2 + 1 0] [ 0 x^2 + 1] - sage: V, from_V, to_V = L.vector_space(); V + sage: V, from_V, to_V = L.vector_space(); V # optional - sage.libs.singular Vector space of dimension 2 over Rational function field in x over Rational Field - sage: I.module().is_submodule(V) + sage: I.module().is_submodule(V) # optional - sage.libs.singular True """ return self._module @@ -1021,10 +1021,10 @@ def gens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(x^2 + 1) - sage: I.gens() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular + sage: I.gens() # optional - sage.libs.singular (x^2 + 1, (x^2 + 1)*y) """ return self._gens @@ -1036,10 +1036,10 @@ def gen(self, i): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(x^2 + 1) - sage: I.gen(1) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular + sage: I.gen(1) # optional - sage.libs.singular (x^2 + 1)*y """ return self._gens[i] @@ -1051,10 +1051,10 @@ def ngens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(x^2 + 1) - sage: I.ngens() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular + sage: I.ngens() # optional - sage.libs.singular 2 """ return len(self._gens) @@ -1066,11 +1066,11 @@ def _add_(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I + J + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: J = O.ideal(x+y) # optional - sage.libs.singular + sage: I + J # optional - sage.libs.singular Ideal ((-x^2 + x)*y + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal(self.gens() + other.gens()) @@ -1082,11 +1082,11 @@ def _mul_(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: J = O.ideal(x+y) - sage: I * J + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: J = O.ideal(x+y) # optional - sage.libs.singular + sage: I * J # optional - sage.libs.singular Ideal ((-x^5 + x^4 - x^2 + x)*y + x^3 + 1, (x^3 - x^2 + 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal([x*y for x in self.gens() for y in other.gens()]) @@ -1098,10 +1098,10 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: x * I + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: x * I # optional - sage.libs.singular Ideal (x^4 + x, -x*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal([other * x for x in self.gens()]) @@ -1113,14 +1113,14 @@ def intersection(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y^3); J = O.ideal(y^2) - sage: Z = I.intersection(J); Z + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y^3); J = O.ideal(y^2) # optional - sage.libs.singular + sage: Z = I.intersection(J); Z # optional - sage.libs.singular Ideal (x^6 + 2*x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: y^2 in Z + sage: y^2 in Z # optional - sage.libs.singular False - sage: y^3 in Z + sage: y^3 in Z # optional - sage.libs.singular True """ if not isinstance(other, FunctionFieldIdeal): @@ -1143,14 +1143,14 @@ def __invert__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: ~I + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: ~I # optional - sage.libs.singular Ideal (-1, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^-1 + sage: I^-1 # optional - sage.libs.singular Ideal (-1, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: ~I * I + sage: ~I * I # optional - sage.libs.singular Ideal (1) of Order in Function field in y defined by y^2 - x^3 - 1 """ if len(self.gens()) == 0: @@ -1320,29 +1320,29 @@ def __contains__(self, x): False sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal([y]); I + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal([y]); I # optional - sage.libs.singular Ideal (y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: x * y in I + sage: x * y in I # optional - sage.libs.singular True - sage: y / x in I + sage: y / x in I # optional - sage.libs.singular False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.singular False - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal([y]); I + sage: K. = FunctionField(QQ); _. = K[] # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal([y]); I # optional - sage.libs.singular Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I + sage: x * y in I # optional - sage.libs.singular True - sage: y / x in I + sage: y / x in I # optional - sage.libs.singular False - sage: y^2 - 2 in I + sage: y^2 - 2 in I # optional - sage.libs.singular False """ from sage.modules.free_module_element import vector @@ -1391,29 +1391,29 @@ def __invert__(self): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: ~I + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: ~I # optional - sage.libs.singular Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I^(-1) + sage: I^(-1) # optional - sage.libs.singular Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: ~I * I + sage: ~I * I # optional - sage.libs.singular Ideal (1) of Maximal order of Function field in y defined by y^2 - x^3 - 1 :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: I = O.ideal(y) - sage: ~I + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: ~I # optional - sage.libs.singular Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) + sage: I^(-1) # optional - sage.libs.singular Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I + sage: ~I * I # optional - sage.libs.singular Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ R = self.ring() @@ -1639,9 +1639,9 @@ def hnf(self): :: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y*(y+1)); I.hnf() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.singular [x^6 + x^3 0] [ x^3 + 1 1] """ @@ -1665,12 +1665,12 @@ def denominator(self): :: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y/(y+1)) - sage: d = I.denominator(); d + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y/(y+1)) # optional - sage.libs.singular + sage: d = I.denominator(); d # optional - sage.libs.singular x^3 - sage: d in O + sage: d in O # optional - sage.libs.singular True """ return self._denominator @@ -1818,13 +1818,13 @@ def is_integral(self): True sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.is_integral() + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular + sage: I.is_integral() # optional - sage.libs.singular False - sage: J = I.denominator() * I - sage: J.is_integral() + sage: J = I.denominator() * I # optional - sage.libs.singular + sage: J.is_integral() # optional - sage.libs.singular True """ return self.denominator() == 1 @@ -1864,15 +1864,15 @@ def ideal_below(self): in x over Finite Field of size 2 sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(x,1/y) - sage: I.ideal_below() + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular + sage: I.ideal_below() # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I - sage: J.ideal_below() + sage: J = I.denominator() * I # optional - sage.libs.singular + sage: J.ideal_below() # optional - sage.libs.singular Ideal (x^3 + x^2 + x) of Maximal order of Rational function field in x over Rational Field """ @@ -1964,10 +1964,10 @@ def is_prime(self): [True, True] sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: [f.is_prime() for f,_ in I.factor()] + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.singular [True, True] """ factors = self.factor() @@ -2084,10 +2084,10 @@ def prime_below(self): Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: O = F.maximal_order() - sage: I = O.ideal(y) - sage: [f.prime_below() for f,_ in I.factor()] + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.singular [Ideal (x) of Maximal order of Rational function field in x over Rational Field, Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Rational Field] """ @@ -2682,9 +2682,9 @@ class FunctionFieldIdealInfinite_module(FunctionFieldIdealInfinite, Ideal_generi EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: O.ideal(y) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.ideal(y) # optional - sage.libs.singular Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ def __init__(self, ring, module): @@ -2694,10 +2694,10 @@ def __init__(self, ring, module): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal(y) - sage: TestSuite(I).run() + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: TestSuite(I).run() # optional - sage.libs.singular """ FunctionFieldIdealInfinite.__init__(self, ring) diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index c38c63d36b0..2199d63d72f 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -10,17 +10,17 @@ sage: K.hom(1/x) Function Field endomorphism of Rational function field in x over Rational Field Defn: x |--> 1/x - sage: L. = K.extension(y^2 - x) - sage: K.hom(y) + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: K.hom(y) # optional - sage.libs.singular Function Field morphism: From: Rational function field in x over Rational Field To: Function field in y defined by y^2 - x Defn: x |--> y - sage: L.hom([y,x]) + sage: L.hom([y,x]) # optional - sage.libs.singular Function Field endomorphism of Function field in y defined by y^2 - x Defn: y |--> y x |--> x - sage: L.hom([x,y]) + sage: L.hom([x,y]) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: invalid morphism @@ -72,9 +72,9 @@ class FunctionFieldVectorSpaceIsomorphism(Morphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) # optional - sage.libs.singular, sage.modules True """ def _repr_(self) -> str: @@ -84,13 +84,13 @@ def _repr_(self) -> str: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f # optional - sage.libs.singular, sage.modules Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 - sage: t + sage: t # optional - sage.libs.singular, sage.modules Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -107,9 +107,9 @@ def is_injective(self) -> bool: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f.is_injective() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f.is_injective() # optional - sage.libs.singular, sage.modules True """ return True @@ -121,9 +121,9 @@ def is_surjective(self) -> bool: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() - sage: f.is_surjective() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f.is_surjective() # optional - sage.libs.singular, sage.modules True """ return True @@ -144,11 +144,11 @@ def _richcmp_(self, other, op): sage: L = K.function_field() sage: f = K.coerce_map_from(L) - sage: K = QQbar['x'].fraction_field() - sage: L = K.function_field() - sage: g = K.coerce_map_from(L) + sage: K = QQbar['x'].fraction_field() # optional - sage.rings.number_field + sage: L = K.function_field() # optional - sage.rings.number_field + sage: g = K.coerce_map_from(L) # optional - sage.rings.number_field - sage: f == g + sage: f == g # optional - sage.rings.number_field False sage: f == f True @@ -187,8 +187,8 @@ class MapVectorSpaceToFunctionField(FunctionFieldVectorSpaceIsomorphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); f # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space(); f # optional - sage.libs.singular, sage.modules Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 @@ -198,8 +198,8 @@ def __init__(self, V, K): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); type(f) # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space(); type(f) # optional - sage.libs.singular, sage.modules """ self._V = V @@ -219,18 +219,18 @@ def _call_(self, v): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() # optional - sage.modules - sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.libs.singular, sage.modules 1/x^3*y + x TESTS: Test that this map is a bijection for some random inputs:: - sage: R. = L[] - sage: M. = L.extension(z^3 - y - x) - sage: for F in [K,L,M]: # optional - sage.modules + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular + sage: for F in [K, L, M]: # optional - sage.libs.singular, sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -262,9 +262,9 @@ def domain(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() # optional - sage.modules - sage: f.domain() # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f.domain() # optional - sage.libs.singular, sage.modules Vector space of dimension 2 over Rational function field in x over Rational Field """ return self._V @@ -276,9 +276,9 @@ def codomain(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() # optional - sage.modules - sage: f.codomain() # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: f.codomain() # optional - sage.libs.singular, sage.modules Function field in y defined by y^2 - x*y + 4*x^3 """ return self._K @@ -291,8 +291,8 @@ class MapFunctionFieldToVectorSpace(FunctionFieldVectorSpaceIsomorphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space(); t # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space(); t # optional - sage.libs.singular, sage.modules Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -310,9 +310,9 @@ def __init__(self, K, V): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() # optional - sage.modules - sage: TestSuite(t).run(skip="_test_category") # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: TestSuite(t).run(skip="_test_category") # optional - sage.libs.singular, sage.modules """ self._V = V self._K = K @@ -327,18 +327,18 @@ def _call_(self, x): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: V, f, t = L.vector_space() # optional - sage.modules - sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules + sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.libs.singular, sage.modules (x, 1/x^3) TESTS: Test that this map is a bijection for some random inputs:: - sage: R. = L[] - sage: M. = L.extension(z^3 - y - x) - sage: for F in [K,L,M]: # optional - sage.modules + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular + sage: for F in [K, L, M]: # optional - sage.libs.singular, sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -392,9 +392,9 @@ def _repr_type(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = L.hom(y*2) # optional - sage.libs.pari - sage: f._repr_type() # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular + sage: f._repr_type() # optional - sage.libs.pari, sage.libs.singular 'Function Field' """ return "Function Field" @@ -406,9 +406,9 @@ def _repr_defn(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = L.hom(y*2) # optional - sage.libs.pari - sage: f._repr_defn() # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular + sage: f._repr_defn() # optional - sage.libs.pari, sage.libs.singular 'y |--> 2*y' """ a = '%s |--> %s' % (self.domain().variable_name(), self._im_gen) @@ -424,13 +424,13 @@ class FunctionFieldMorphism_polymod(FunctionFieldMorphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = L.hom(y*2); f # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular + sage: f = L.hom(y*2); f # optional - sage.libs.pari, sage.libs.singular Function Field endomorphism of Function field in y defined by y^3 + 6*x^3 + x Defn: y |--> 2*y - sage: factor(L.polynomial()) # optional - sage.libs.pari + sage: factor(L.polynomial()) # optional - sage.libs.pari, sage.libs.singular y^3 + 6*x^3 + x - sage: f(y).charpoly('y') # optional - sage.libs.pari + sage: f(y).charpoly('y') # optional - sage.libs.pari, sage.libs.singular y^3 + 6*x^3 + x """ def __init__(self, parent, im_gen, base_morphism): @@ -440,9 +440,9 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = L.hom(y*2) # optional - sage.libs.pari - sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular + sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari, sage.libs.singular """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -459,10 +459,10 @@ def _call_(self, x): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari - sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular + sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari, sage.libs.singular 2/x*y + x^2/(x + 1) - sage: f(y) # optional - sage.libs.pari + sage: f(y) # optional - sage.libs.pari, sage.libs.singular 2*y """ v = x.list() diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index 48044eec3ab..5df02b11f3a 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -270,10 +270,10 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) - sage: y.is_integral() + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: y.is_integral() # optional - sage.libs.singular False - sage: L.order(y) + sage: L.order(y) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, y^2, y^3, y^4) must be closed under multiplication @@ -282,11 +282,11 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: L.order(L(x)) + sage: L.order(L(x)) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: basis (1, x, x^2, x^3, x^4) is not linearly independent - sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) + sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: basis (y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x) is not linearly independent @@ -597,7 +597,7 @@ def __init__(self, basis, check=True): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage: O = L.equation_order_infinite() # optional - sage.libs.pari, sage.modules - sage: TestSuite(O).run() + sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -744,8 +744,8 @@ def ideal(self, *gens): sage: K. = FunctionField(QQ); R. = K[] sage: O = K.maximal_order_infinite() sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) - sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) # optional - sage.libs.singular """ if len(gens) == 1: gens = gens[0] @@ -764,10 +764,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.polynomial() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.polynomial() # optional - sage.libs.pari y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -895,9 +895,9 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) # optional - sage.libs.singular Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ideal(gens) @@ -1548,9 +1548,9 @@ def polynomial(self): y^4 + x*y + 4*x + 1 sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() # optional - sage.modules - sage: O.polynomial() # optional - sage.modules + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular, sage.modules + sage: O.polynomial() # optional - sage.libs.singular, sage.modules y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -1570,9 +1570,9 @@ def basis(self): sage: K. = FunctionField(QQ) sage: R. = PolynomialRing(K) - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) - sage: O = F.maximal_order() # optional - sage.modules - sage: O.basis() # optional - sage.modules + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular, sage.modules + sage: O.basis() # optional - sage.libs.singular, sage.modules (1, 1/x^4*y, 1/x^9*y^2, 1/x^13*y^3) """ return self._basis @@ -1652,10 +1652,10 @@ def coordinate_vector(self, e): (0, x, 0, 0) sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() # optional - sage.modules - sage: f = (x + y)^3 # optional - sage.modules - sage: O.coordinate_vector(f) # optional - sage.modules + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular, sage.modules + sage: f = (x + y)^3 # optional - sage.libs.singular, sage.modules + sage: O.coordinate_vector(f) # optional - sage.libs.singular, sage.modules (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e)) @@ -2694,9 +2694,9 @@ def decomposition(self): :: sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() # optional - sage.modules - sage: Oinf.decomposition() # optional - sage.modules + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.singular, sage.modules + sage: Oinf.decomposition() # optional - sage.libs.singular, sage.modules [(Ideal (1/x^2*y - 1) of Maximal infinite order of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -2705,9 +2705,9 @@ def decomposition(self): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() # optional - sage.modules - sage: Oinf.decomposition() # optional - sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.singular, sage.modules + sage: Oinf.decomposition() # optional - sage.libs.singular, sage.modules [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] """ diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 6a28865041b..6cfc350459e 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -866,10 +866,10 @@ def _residue_field(self, name=None): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + Y - x^4) + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular sage: O = K.maximal_order() sage: I = O.ideal(x) - sage: [p.residue_field() for p in L.places_above(I.place())] + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular [(Rational Field, Ring morphism: From: Rational Field To: Valuation ring at Place (x, y, y^2), Ring morphism: @@ -880,7 +880,7 @@ def _residue_field(self, name=None): To: Valuation ring at Place (x, x*y, y^2 + 1), Ring morphism: From: Valuation ring at Place (x, x*y, y^2 + 1) To: Number Field in s with defining polynomial x^2 - 2*x + 2)] - sage: for p in L.places_above(I.place()): + sage: for p in L.places_above(I.place()): # optional - sage.libs.singular ....: k, fr_k, to_k = p.residue_field() ....: assert all(fr_k(k(e)) == e for e in range(10)) ....: assert all(to_k(fr_k(e)) == e for e in [k.random_element() for i in [1..10]]) @@ -888,10 +888,10 @@ def _residue_field(self, name=None): :: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.rings.number_field - sage: I = O.ideal(x) # optional - sage.rings.number_field - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.rings.number_field + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular, sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular, sage.rings.number_field + sage: I = O.ideal(x) # optional - sage.libs.singular, sage.rings.number_field + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular, sage.rings.number_field [(Algebraic Field, Ring morphism: From: Algebraic Field To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: @@ -1115,10 +1115,10 @@ def valuation_ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: p = L.places_finite()[0] - sage: p.valuation_ring() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: p.valuation_ring() # optional - sage.libs.pari Valuation ring at Place (x, x*y) """ from .valuation_ring import FunctionFieldValuationRing From 0587b8281e1299662a993d6a70b52201f8104263 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 14:34:58 -0800 Subject: [PATCH 17/54] src/sage/rings/function_field/function_field_valuation.py: Fix up # optional --- src/sage/rings/function_field/function_field_valuation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index fddb2e6dd4f..11b2c773f9d 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -1432,7 +1432,7 @@ class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative TESTS:: sage: from sage.rings.function_field.function_field_valuation import FunctionFieldExtensionMappedValuation - sage: isinstance(w, FunctionFieldExtensionMappedValuation) + sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari True """ From 31ad4be0dfb05c58763429960a51f44a1df84ccf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 14:35:19 -0800 Subject: [PATCH 18/54] src/sage/rings/function_field/derivations.py: Fix imports in doctests --- src/sage/rings/function_field/derivations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index efa59c00bfa..cb5715284a2 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -515,7 +515,7 @@ def _pth_root_in_prime_field(e): TESTS:: - sage: from sage.rings.function_field.maps import _pth_root_in_prime_field + sage: from sage.rings.function_field.derivations import _pth_root_in_prime_field sage: p = 5 sage: F. = GF(p) # optional - sage.libs.pari sage: e = F.random_element() # optional - sage.libs.pari @@ -531,7 +531,7 @@ def _pth_root_in_finite_field(e): TESTS:: - sage: from sage.rings.function_field.maps import _pth_root_in_finite_field + sage: from sage.rings.function_field.derivations import _pth_root_in_finite_field sage: p = 3 sage: F. = GF(p^2) # optional - sage.libs.pari sage: e = F.random_element() # optional - sage.libs.pari From e1d2af770b14c5d78cebf01963ce0f3ccdfaef4d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 6 Mar 2023 15:03:32 -0800 Subject: [PATCH 19/54] src/sage/rings/function_field/function_field.py: Fix # optional --- src/sage/rings/function_field/function_field.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index eeb27a6d825..4eb0477e6e0 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -1049,8 +1049,8 @@ def divisor_group(self): Divisor group of Rational function field in t over Rational Field sage: _. = K[] - sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.singular - sage: L.divisor_group() # optional - sage.modules, sage.singular + sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.libs.singular + sage: L.divisor_group() # optional - sage.modules, sage.libs.singular Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari From a1083b7ba1136fd2ecba1341edfd8209de4ae113 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 7 Mar 2023 21:40:13 -0800 Subject: [PATCH 20/54] src/sage/rings/function_field/maps.py: Fill in PR number for deprecation --- src/sage/rings/function_field/maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 2199d63d72f..5059a88d6a7 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -62,7 +62,7 @@ "RationalFunctionFieldHigherDerivation_global", "FunctionFieldHigherDerivation_global", "FunctionFieldHigherDerivation_char_zero", -), deprecation=99999) +), deprecation=35230) class FunctionFieldVectorSpaceIsomorphism(Morphism): From 3a6bb7f5d864eee1aae02b1f20a3b72159c9dd60 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 10 Mar 2023 13:00:37 -0800 Subject: [PATCH 21/54] src/sage/rings/function_field: In # optional, no commas between tags --- src/sage/rings/function_field/derivations.py | 36 +- src/sage/rings/function_field/element.pyx | 84 ++--- .../rings/function_field/function_field.py | 130 +++---- .../function_field_valuation.py | 6 +- src/sage/rings/function_field/maps.py | 80 ++--- src/sage/rings/function_field/order.py | 334 +++++++++--------- src/sage/rings/function_field/place.py | 8 +- 7 files changed, 339 insertions(+), 339 deletions(-) diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index cb5715284a2..70062ce1fea 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -746,11 +746,11 @@ class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari, sage.modules + sage: h # optional - sage.libs.pari sage.modules Higher derivation map: From: Function field in y defined by y^3 + x^3*y + x To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) # optional - sage.libs.pari, sage.modules + sage: h(y^2, 2) # optional - sage.libs.pari sage.modules ((x^7 + 1)/x^2)*y^2 + x^3*y """ @@ -762,8 +762,8 @@ def __init__(self, field): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari, sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari sage.modules """ from sage.matrix.constructor import matrix @@ -790,8 +790,8 @@ def _call_with_args(self, f, args, kwds): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari, sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari sage.modules ((x^7 + 1)/x^2)*y^2 + x^3*y """ return self._derive(f, *args, **kwds) @@ -807,18 +807,18 @@ def _derive(self, f, i, separating_element=None): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: y^3 # optional - sage.libs.pari, sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: y^3 # optional - sage.libs.pari sage.modules x^3*y + x - sage: h._derive(y^3,0) # optional - sage.libs.pari, sage.modules + sage: h._derive(y^3,0) # optional - sage.libs.pari sage.modules x^3*y + x - sage: h._derive(y^3,1) # optional - sage.libs.pari, sage.modules + sage: h._derive(y^3,1) # optional - sage.libs.pari sage.modules x^4*y^2 + 1 - sage: h._derive(y^3,2) # optional - sage.libs.pari, sage.modules + sage: h._derive(y^3,2) # optional - sage.libs.pari sage.modules x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) # optional - sage.libs.pari, sage.modules + sage: h._derive(y^3,3) # optional - sage.libs.pari sage.modules (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) # optional - sage.libs.pari, sage.modules + sage: h._derive(y^3,4) # optional - sage.libs.pari sage.modules (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y """ F = self._field @@ -906,9 +906,9 @@ def _prime_power_representation(self, f, separating_element=None): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: b = h._prime_power_representation(y) # optional - sage.libs.pari, sage.modules - sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari, sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: b = h._prime_power_representation(y) # optional - sage.libs.pari sage.modules + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari sage.modules True """ F = self._field @@ -952,8 +952,8 @@ def _pth_root(self, c): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari, sage.modules - sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari, sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari sage.modules y^2 + x^2 """ from sage.modules.free_module_element import vector diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index c5333ed7569..5555e73c904 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -186,10 +186,10 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.matrix() # optional - sage.libs.singular, sage.modules + sage: y.matrix() # optional - sage.libs.singular sage.modules [ 0 1] [-4*x^3 x] - sage: y.matrix().charpoly('Z') # optional - sage.libs.singular, sage.modules + sage: y.matrix().charpoly('Z') # optional - sage.libs.singular sage.modules Z^2 - x*Z + 4*x^3 An example in a relative extension, where neither function @@ -200,18 +200,18 @@ cdef class FunctionFieldElement(FieldElement): sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular sage: M. = L[] # optional - sage.libs.singular sage: Z. = L.extension(T^3 - y^2*T + x) # optional - sage.libs.singular - sage: alpha.matrix() # optional - sage.libs.singular, sage.modules + sage: alpha.matrix() # optional - sage.libs.singular sage.modules [ 0 1 0] [ 0 0 1] [ -x x*y - 4*x^3 0] - sage: alpha.matrix(K) # optional - sage.libs.singular, sage.modules + sage: alpha.matrix(K) # optional - sage.libs.singular sage.modules [ 0 0 1 0 0 0] [ 0 0 0 1 0 0] [ 0 0 0 0 1 0] [ 0 0 0 0 0 1] [ -x 0 -4*x^3 x 0 0] [ 0 -x -4*x^4 -4*x^3 + x^2 0 0] - sage: alpha.matrix(Z) # optional - sage.libs.singular, sage.modules + sage: alpha.matrix(Z) # optional - sage.libs.singular sage.modules [alpha] We show that this matrix does indeed work as expected when making a @@ -220,12 +220,12 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: V, from_V, to_V = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: y5 = to_V(y^5); y5 # optional - sage.libs.singular, sage.modules + sage: V, from_V, to_V = L.vector_space() # optional - sage.libs.singular sage.modules + sage: y5 = to_V(y^5); y5 # optional - sage.libs.singular sage.modules ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y4y = to_V(y^4) * y.matrix(); y4y # optional - sage.libs.singular, sage.modules + sage: y4y = to_V(y^4) * y.matrix(); y4y # optional - sage.libs.singular sage.modules ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y5 == y4y # optional - sage.libs.singular, sage.modules + sage: y5 == y4y # optional - sage.libs.singular sage.modules True """ # multiply each element of the vector space isomorphic to the parent @@ -248,7 +248,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.trace() # optional - sage.libs.singular, sage.modules + sage: y.trace() # optional - sage.libs.singular sage.modules x """ return self.matrix().trace() @@ -261,7 +261,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.norm() # optional - sage.libs.singular, sage.modules + sage: y.norm() # optional - sage.libs.singular sage.modules 4*x^3 The norm is relative:: @@ -269,9 +269,9 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: z.norm() # optional - sage.libs.singular, sage.modules + sage: z.norm() # optional - sage.libs.singular sage.modules -x - sage: z.norm().parent() # optional - sage.libs.singular, sage.modules + sage: z.norm().parent() # optional - sage.libs.singular sage.modules Function field in y defined by y^2 - x*y + 4*x^3 """ return self.matrix().determinant() @@ -322,11 +322,11 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: x.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: x.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules W - x - sage: y.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: y.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules W^2 - x*W + 4*x^3 - sage: z.characteristic_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: z.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().characteristic_polynomial(*args, **kwds) @@ -343,11 +343,11 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: x.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: x.minimal_polynomial('W') # optional - sage.libs.singular sage.modules W - x - sage: y.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: y.minimal_polynomial('W') # optional - sage.libs.singular sage.modules W^2 - x*W + 4*x^3 - sage: z.minimal_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: z.minimal_polynomial('W') # optional - sage.libs.singular sage.modules W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().minimal_polynomial(*args, **kwds) @@ -364,13 +364,13 @@ cdef class FunctionFieldElement(FieldElement): sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular sage: y.is_integral() # optional - sage.libs.singular True - sage: (y/x).is_integral() # optional - sage.libs.singular, sage.modules + sage: (y/x).is_integral() # optional - sage.libs.singular sage.modules True - sage: (y/x)^2 - (y/x) + 4*x # optional - sage.libs.singular, sage.modules + sage: (y/x)^2 - (y/x) + 4*x # optional - sage.libs.singular sage.modules 0 - sage: (y/x^2).is_integral() # optional - sage.libs.singular, sage.modules + sage: (y/x^2).is_integral() # optional - sage.libs.singular sage.modules False - sage: (y/x).minimal_polynomial('W') # optional - sage.libs.singular, sage.modules + sage: (y/x).minimal_polynomial('W') # optional - sage.libs.singular sage.modules W^2 - W + 4*x """ R = self.parent().base_field().maximal_order() @@ -389,7 +389,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari - sage: (y^3 + x).differential() # optional - sage.libs.pari, sage.modules + sage: (y^3 + x).differential() # optional - sage.libs.pari sage.modules (((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3) d(x) TESTS: @@ -402,11 +402,11 @@ cdef class FunctionFieldElement(FieldElement): sage: R. = L[] # optional - sage.libs.pari sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: x.differential() # optional - sage.libs.pari, sage.modules + sage: x.differential() # optional - sage.libs.pari sage.modules d(x) - sage: y.differential() # optional - sage.libs.pari, sage.modules + sage: y.differential() # optional - sage.libs.pari sage.modules (16/x*y) d(x) - sage: z.differential() # optional - sage.libs.pari, sage.modules + sage: z.differential() # optional - sage.libs.pari sage.modules (8/x*z) d(x) """ F = self.parent() @@ -429,7 +429,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).derivative() # optional - sage.libs.pari, sage.modules + sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.modules ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 """ D = self.parent().derivation() @@ -451,14 +451,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = t^2 # optional - sage.libs.pari - sage: f.higher_derivative(2) # optional - sage.libs.pari, sage.modules + sage: f.higher_derivative(2) # optional - sage.libs.pari sage.modules 1 :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari, sage.modules + sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari sage.modules 1/x^3*y + (x^6 + x^4 + x^3 + x^2 + x + 1)/x^5 """ D = self.parent().higher_derivation() @@ -473,7 +473,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor() # optional - sage.libs.pari, sage.modules + sage: f.divisor() # optional - sage.libs.pari sage.modules 3*Place (1/x) - Place (x) - Place (x^2 + x + 1) @@ -482,7 +482,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: y.divisor() # optional - sage.libs.pari, sage.modules + sage: y.divisor() # optional - sage.libs.pari sage.modules - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -503,14 +503,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_zeros() # optional - sage.libs.pari, sage.modules + sage: f.divisor_of_zeros() # optional - sage.libs.pari sage.modules 3*Place (1/x) :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari, sage.modules + sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari sage.modules 3*Place (x, x*y) """ if self.is_zero(): @@ -529,7 +529,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_poles() # optional - sage.libs.pari, sage.modules + sage: f.divisor_of_poles() # optional - sage.libs.pari sage.modules Place (x) + Place (x^2 + x + 1) @@ -537,7 +537,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_poles() # optional - sage.libs.pari, sage.modules + sage: (x/y).divisor_of_poles() # optional - sage.libs.pari sage.modules Place (1/x, 1/x*y) + 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -556,14 +556,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.zeros() # optional - sage.libs.pari, sage.modules + sage: f.zeros() # optional - sage.libs.pari sage.modules [Place (1/x)] :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).zeros() # optional - sage.libs.pari, sage.modules + sage: (x/y).zeros() # optional - sage.libs.pari sage.modules [Place (x, x*y)] """ return self.divisor_of_zeros().support() @@ -576,14 +576,14 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.poles() # optional - sage.libs.pari, sage.modules + sage: f.poles() # optional - sage.libs.pari sage.modules [Place (x), Place (x^2 + x + 1)] :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).poles() # optional - sage.libs.pari, sage.modules + sage: (x/y).poles() # optional - sage.libs.pari sage.modules [Place (1/x, 1/x*y), Place (x + 1, x*y)] """ return self.divisor_of_poles().support() @@ -600,8 +600,8 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_infinite()[0] # optional - sage.libs.pari, sage.modules - sage: y.valuation(p) # optional - sage.libs.pari, sage.modules + sage: p = L.places_infinite()[0] # optional - sage.libs.pari sage.modules + sage: y.valuation(p) # optional - sage.libs.pari sage.modules -1 :: diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 4eb0477e6e0..80bdcf96c42 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -24,31 +24,31 @@ simple arithmetic in it:: sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari sage.libs.singular Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: y^2 # optional - sage.libs.pari, sage.libs.singular + sage: y^2 # optional - sage.libs.pari sage.libs.singular y^2 - sage: y^3 # optional - sage.libs.pari, sage.libs.singular + sage: y^3 # optional - sage.libs.pari sage.libs.singular 2*x*y + (x^4 + 1)/x - sage: a = 1/y; a # optional - sage.libs.pari, sage.libs.singular + sage: a = 1/y; a # optional - sage.libs.pari sage.libs.singular (x/(x^4 + 1))*y^2 + 3*x^2/(x^4 + 1) - sage: a * y # optional - sage.libs.pari, sage.libs.singular + sage: a * y # optional - sage.libs.pari sage.libs.singular 1 We next make an extension of the above function field, illustrating that arithmetic with a tower of three fields is fully supported:: sage: S. = L[] # optional - sage.libs.pari - sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari, sage.libs.singular - sage: M # optional - sage.libs.pari, sage.libs.singular + sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari sage.libs.singular + sage: M # optional - sage.libs.pari sage.libs.singular Function field in t defined by t^2 + 4*x*y - sage: t^2 # optional - sage.libs.pari, sage.libs.singular + sage: t^2 # optional - sage.libs.pari sage.libs.singular x*y - sage: 1/t # optional - sage.libs.pari, sage.libs.singular + sage: 1/t # optional - sage.libs.pari sage.libs.singular ((1/(x^4 + 1))*y^2 + 3*x/(x^4 + 1))*t - sage: M.base_field() # optional - sage.libs.pari, sage.libs.singular + sage: M.base_field() # optional - sage.libs.pari sage.libs.singular Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: M.base_field().base_field() # optional - sage.libs.pari, sage.libs.singular + sage: M.base_field().base_field() # optional - sage.libs.pari sage.libs.singular Rational function field in x over Finite Field in a of size 5^2 It is also possible to construct function fields over an imperfect base field:: @@ -60,7 +60,7 @@ sage: J. = FunctionField(GF(5)); J # optional - sage.libs.pari Rational function field in x over Finite Field of size 5 sage: T. = J[] # optional - sage.libs.pari - sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari, sage.libs.singular + sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari sage.libs.singular Function field in v defined by v^5 + 4*x Function fields over the rational field are supported:: @@ -100,32 +100,32 @@ Function fields over the algebraic field are supported:: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular, sage.rings.number_field - sage: O = L.maximal_order() # optional - sage.libs.singular, sage.rings.number_field - sage: I = O.ideal(y) # optional - sage.libs.singular, sage.rings.number_field - sage: I.divisor() # optional - sage.libs.singular, sage.rings.number_field + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular sage.rings.number_field + sage: O = L.maximal_order() # optional - sage.libs.singular sage.rings.number_field + sage: I = O.ideal(y) # optional - sage.libs.singular sage.rings.number_field + sage: I.divisor() # optional - sage.libs.singular sage.rings.number_field Place (x - I, x*y) - Place (x, x*y) + Place (x + I, x*y) - sage: pl = I.divisor().support()[0] # optional - sage.libs.singular, sage.rings.number_field - sage: m = L.completion(pl, prec=5) # optional - sage.libs.singular, sage.rings.number_field - sage: m(x) # optional - sage.libs.singular, sage.rings.number_field + sage: pl = I.divisor().support()[0] # optional - sage.libs.singular sage.rings.number_field + sage: m = L.completion(pl, prec=5) # optional - sage.libs.singular sage.rings.number_field + sage: m(x) # optional - sage.libs.singular sage.rings.number_field I + s + O(s^5) - sage: m(y) # long time (4s) # optional - sage.libs.singular, sage.rings.number_field + sage: m(y) # long time (4s) # optional - sage.libs.singular sage.rings.number_field -2*s + (-4 - I)*s^2 + (-15 - 4*I)*s^3 + (-75 - 23*I)*s^4 + (-413 - 154*I)*s^5 + O(s^6) - sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.libs.singular, sage.rings.number_field + sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.libs.singular sage.rings.number_field O(s^5) TESTS:: sage: TestSuite(J).run() # optional - sage.libs.pari sage: TestSuite(K).run(max_runs=256) # long time (10s) # optional - sage.rings.number_field - sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.libs.singular, sage.rings.number_field + sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.libs.singular sage.rings.number_field sage: TestSuite(M).run(max_runs=8) # long time (35s) sage: TestSuite(N).run(max_runs=8, skip = '_test_derivation') # long time (15s) - sage: TestSuite(O).run() # optional - sage.libs.singular, sage.rings.number_field + sage: TestSuite(O).run() # optional - sage.libs.singular sage.rings.number_field sage: TestSuite(R).run() - sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.singular, sage.libs.pari + sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.singular sage.libs.pari Global function fields ---------------------- @@ -164,7 +164,7 @@ sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage: L.genus() # optional - sage.libs.pari 3 - sage: L.weierstrass_places() # optional - sage.libs.pari, sage.modules + sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -175,17 +175,17 @@ Place (x^3 + x^2 + 1, y + x), Place (x^3 + x^2 + 1, y + x^2 + 1), Place (x^3 + x^2 + 1, y + x^2 + x + 1)] - sage: L.gaps() # optional - sage.libs.pari, sage.modules + sage: L.gaps() # optional - sage.libs.pari sage.modules [1, 2, 3] The gap numbers for Weierstrass places are of course not ordinary:: - sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari, sage.modules - sage: p1.gaps() # optional - sage.libs.pari, sage.modules + sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari sage.modules + sage: p1.gaps() # optional - sage.libs.pari sage.modules [1, 2, 4] - sage: p2.gaps() # optional - sage.libs.pari, sage.modules + sage: p2.gaps() # optional - sage.libs.pari sage.modules [1, 2, 4] - sage: p3.gaps() # optional - sage.libs.pari, sage.modules + sage: p3.gaps() # optional - sage.libs.pari sage.modules [1, 2, 4] AUTHORS: @@ -510,9 +510,9 @@ def order(self, x, check=True): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: O = L.order(y); O # optional - sage.libs.singular, sage.modules + sage: O = L.order(y); O # optional - sage.libs.singular sage.modules Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular, sage.modules + sage: O.basis() # optional - sage.libs.singular sage.modules (1, y, y^2) sage: Z = K.order(x); Z # optional - sage.modules @@ -601,7 +601,7 @@ def order_infinite(self, x, check=True): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: L.order_infinite(y) # todo: not implemented # optional - sage.libs.singular, sage.modules + sage: L.order_infinite(y) # todo: not implemented # optional - sage.libs.singular sage.modules sage: Z = K.order(x); Z # optional - sage.modules Order in Rational function field in x over Rational Field @@ -644,7 +644,7 @@ def _coerce_map_from_(self, source): Conversion map: From: Order in Function field in y defined by y^3 + x^3 + 4*x + 1 To: Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari, sage.libs.singular + sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari sage.libs.singular sage: K. = FunctionField(QQ) sage: L. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field @@ -664,7 +664,7 @@ def _coerce_map_from_(self, source): sage: R. = K[] sage: L. = K.extension(I^2 + 1) # optional - sage.libs.pari sage: M. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field - sage: M.has_coerce_map_from(L) # optional - sage.libs.pari, sage.rings.number_field + sage: M.has_coerce_map_from(L) # optional - sage.libs.pari sage.rings.number_field True Check that :trac:`31072` is fixed:: @@ -977,7 +977,7 @@ def space_of_differentials(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_differentials() # optional - sage.libs.pari, sage.modules + sage: L.space_of_differentials() # optional - sage.libs.pari sage.modules Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ @@ -1001,7 +1001,7 @@ def space_of_holomorphic_differentials(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari, sage.modules + sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules (Vector space of dimension 4 over Finite Field of size 5, Linear map: From: Vector space of dimension 4 over Finite Field of size 5 @@ -1028,7 +1028,7 @@ def basis_of_holomorphic_differentials(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari, sage.modules + sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules [((x/(x^3 + 4))*y) d(x), ((1/(x^3 + 4))*y) d(x), ((x/(x^3 + 4))*y^2) d(x), @@ -1050,12 +1050,12 @@ def divisor_group(self): sage: _. = K[] sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.libs.singular - sage: L.divisor_group() # optional - sage.modules, sage.libs.singular + sage: L.divisor_group() # optional - sage.modules sage.libs.singular Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.divisor_group() # optional - sage.libs.pari, sage.modules + sage: L.divisor_group() # optional - sage.libs.pari sage.modules Divisor group of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ from .divisor import DivisorGroup @@ -1883,48 +1883,48 @@ def free_module(self, base=None, basis=None, map=True): We get the vector spaces, and maps back and forth:: - sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular, sage.modules - sage: V # optional - sage.libs.singular, sage.modules + sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular sage.modules + sage: V # optional - sage.libs.singular sage.modules Vector space of dimension 5 over Rational function field in x over Rational Field - sage: from_V # optional - sage.libs.singular, sage.modules + sage: from_V # optional - sage.libs.singular sage.modules Isomorphism: From: Vector space of dimension 5 over Rational function field in x over Rational Field To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: to_V # optional - sage.libs.singular, sage.modules + sage: to_V # optional - sage.libs.singular sage.modules Isomorphism: From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Vector space of dimension 5 over Rational function field in x over Rational Field We convert an element of the vector space back to the function field:: - sage: from_V(V.1) # optional - sage.libs.singular, sage.modules + sage: from_V(V.1) # optional - sage.libs.singular sage.modules y We define an interesting element of the function field:: - sage: a = 1/L.0; a # optional - sage.libs.singular, sage.modules + sage: a = 1/L.0; a # optional - sage.libs.singular sage.modules (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1) We convert it to the vector space, and get a vector over the base field:: - sage: to_V(a) # optional - sage.libs.singular, sage.modules + sage: to_V(a) # optional - sage.libs.singular sage.modules (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1)) We convert to and back, and get the same element:: - sage: from_V(to_V(a)) == a # optional - sage.libs.singular, sage.modules + sage: from_V(to_V(a)) == a # optional - sage.libs.singular sage.modules True In the other direction:: - sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular, sage.modules - sage: to_V(from_V(v)) == v # optional - sage.libs.singular, sage.modules + sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular sage.modules + sage: to_V(from_V(v)) == v # optional - sage.libs.singular sage.modules True And we show how it works over an extension of an extension field:: sage: R2. = L[]; M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.free_module() # optional - sage.libs.singular, sage.modules + sage: M.free_module() # optional - sage.libs.singular sage.modules (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism: From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Function field in z defined by z^2 - y, Isomorphism: @@ -1933,7 +1933,7 @@ def free_module(self, base=None, basis=None, map=True): We can also get the vector space of ``M`` over ``K``:: - sage: M.free_module(K) # optional - sage.libs.singular, sage.modules + sage: M.free_module(K) # optional - sage.libs.singular sage.modules (Vector space of dimension 10 over Rational function field in x over Rational Field, Isomorphism: From: Vector space of dimension 10 over Rational function field in x over Rational Field To: Function field in z defined by z^2 - y, Isomorphism: @@ -2891,11 +2891,11 @@ def places_above(self, p): True sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular, sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular, sage.rings.number_field - sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular, sage.rings.number_field + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field + sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular sage.rings.number_field ....: for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular, sage.rings.number_field + sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular sage.rings.number_field ....: for p in pls for q in F.places_above(p)) True """ @@ -3069,7 +3069,7 @@ def higher_derivation(self): sage: K. = FunctionField(QQ); _. = K[] sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular - sage: L.higher_derivation() # optional - sage.libs.singular, sage.modules + sage: L.higher_derivation() # optional - sage.libs.singular sage.modules Higher derivation map: From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) @@ -3153,7 +3153,7 @@ def higher_derivation(self): sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.higher_derivation() # optional - sage.libs.pari, sage.modules + sage: L.higher_derivation() # optional - sage.libs.pari sage.modules Higher derivation map: From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) @@ -3322,7 +3322,7 @@ def gaps(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.gaps() # optional - sage.libs.pari, sage.modules + sage: L.gaps() # optional - sage.libs.pari sage.modules [1, 2, 3] """ return self._weierstrass_places()[1] @@ -3335,7 +3335,7 @@ def weierstrass_places(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.weierstrass_places() # optional - sage.libs.pari, sage.modules + sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -3359,7 +3359,7 @@ def _weierstrass_places(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari, sage.modules + sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari sage.modules 10 This method implements Algorithm 30 in [Hes2002b]_. @@ -3781,7 +3781,7 @@ class RationalFunctionField(FunctionField): sage: R. = FunctionField(QQ) sage: L. = R[] sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular - sage: (y/x).divisor() # optional - sage.libs.singular, sage.modules + sage: (y/x).divisor() # optional - sage.libs.singular sage.modules - Place (x, y - 1) - Place (x, y + 1) + Place (x^2 + 1, y) @@ -3790,15 +3790,15 @@ class RationalFunctionField(FunctionField): sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field sage: R. = FunctionField(NF) # optional - sage.rings.number_field sage: L. = R[] # optional - sage.rings.number_field - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular, sage.modules, sage.rings.number_field + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular sage.modules sage.rings.number_field - sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular, sage.modules, sage.rings.number_field + sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field -2*Place (1/x, 1/x*y - 1) - 2*Place (1/x, 1/x*y + 1) + Place (x, y - 1) + Place (x, y + 1) - sage: (x/y).divisor() # optional - sage.libs.singular, sage.modules, sage.rings.number_field + sage: (x/y).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field - Place (x - i, y) + Place (x, y - 1) + Place (x, y + 1) diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index 11b2c773f9d..b12090991ee 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -353,9 +353,9 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari, sage.libs.singular - sage: v = K.valuation(1/x) # optional - sage.libs.pari, sage.libs.singular - sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.libs.singular + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.libs.singular + sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.libs.singular """ from sage.categories.function_fields import FunctionFields diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 5059a88d6a7..f09be93318c 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -73,8 +73,8 @@ class FunctionFieldVectorSpaceIsomorphism(Morphism): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) # optional - sage.libs.singular sage.modules True """ def _repr_(self) -> str: @@ -85,12 +85,12 @@ def _repr_(self) -> str: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f # optional - sage.libs.singular sage.modules Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 - sage: t # optional - sage.libs.singular, sage.modules + sage: t # optional - sage.libs.singular sage.modules Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -108,8 +108,8 @@ def is_injective(self) -> bool: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f.is_injective() # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f.is_injective() # optional - sage.libs.singular sage.modules True """ return True @@ -122,8 +122,8 @@ def is_surjective(self) -> bool: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f.is_surjective() # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f.is_surjective() # optional - sage.libs.singular sage.modules True """ return True @@ -188,7 +188,7 @@ class MapVectorSpaceToFunctionField(FunctionFieldVectorSpaceIsomorphism): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); f # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space(); f # optional - sage.libs.singular sage.modules Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 @@ -199,7 +199,7 @@ def __init__(self, V, K): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); type(f) # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space(); type(f) # optional - sage.libs.singular sage.modules """ self._V = V @@ -220,8 +220,8 @@ def _call_(self, v): sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.libs.singular sage.modules 1/x^3*y + x TESTS: @@ -230,7 +230,7 @@ def _call_(self, v): sage: R. = L[] # optional - sage.libs.singular sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular - sage: for F in [K, L, M]: # optional - sage.libs.singular, sage.modules + sage: for F in [K, L, M]: # optional - sage.libs.singular sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -263,8 +263,8 @@ def domain(self): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f.domain() # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f.domain() # optional - sage.libs.singular sage.modules Vector space of dimension 2 over Rational function field in x over Rational Field """ return self._V @@ -277,8 +277,8 @@ def codomain(self): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: f.codomain() # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: f.codomain() # optional - sage.libs.singular sage.modules Function field in y defined by y^2 - x*y + 4*x^3 """ return self._K @@ -292,7 +292,7 @@ class MapFunctionFieldToVectorSpace(FunctionFieldVectorSpaceIsomorphism): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); t # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space(); t # optional - sage.libs.singular sage.modules Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -311,8 +311,8 @@ def __init__(self, K, V): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: TestSuite(t).run(skip="_test_category") # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: TestSuite(t).run(skip="_test_category") # optional - sage.libs.singular sage.modules """ self._V = V self._K = K @@ -328,8 +328,8 @@ def _call_(self, x): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular, sage.modules - sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.libs.singular, sage.modules + sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules + sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.libs.singular sage.modules (x, 1/x^3) TESTS: @@ -338,7 +338,7 @@ def _call_(self, x): sage: R. = L[] # optional - sage.libs.singular sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular - sage: for F in [K, L, M]: # optional - sage.libs.singular, sage.modules + sage: for F in [K, L, M]: # optional - sage.libs.singular sage.modules ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -392,9 +392,9 @@ def _repr_type(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular - sage: f._repr_type() # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular + sage: f._repr_type() # optional - sage.libs.pari sage.libs.singular 'Function Field' """ return "Function Field" @@ -406,9 +406,9 @@ def _repr_defn(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular - sage: f._repr_defn() # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular + sage: f._repr_defn() # optional - sage.libs.pari sage.libs.singular 'y |--> 2*y' """ a = '%s |--> %s' % (self.domain().variable_name(), self._im_gen) @@ -424,13 +424,13 @@ class FunctionFieldMorphism_polymod(FunctionFieldMorphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular - sage: f = L.hom(y*2); f # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular + sage: f = L.hom(y*2); f # optional - sage.libs.pari sage.libs.singular Function Field endomorphism of Function field in y defined by y^3 + 6*x^3 + x Defn: y |--> 2*y - sage: factor(L.polynomial()) # optional - sage.libs.pari, sage.libs.singular + sage: factor(L.polynomial()) # optional - sage.libs.pari sage.libs.singular y^3 + 6*x^3 + x - sage: f(y).charpoly('y') # optional - sage.libs.pari, sage.libs.singular + sage: f(y).charpoly('y') # optional - sage.libs.pari sage.libs.singular y^3 + 6*x^3 + x """ def __init__(self, parent, im_gen, base_morphism): @@ -440,9 +440,9 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari, sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular - sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular + sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari sage.libs.singular """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -459,10 +459,10 @@ def _call_(self, x): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari, sage.libs.singular - sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari, sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular + sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari sage.libs.singular 2/x*y + x^2/(x + 1) - sage: f(y) # optional - sage.libs.pari, sage.libs.singular + sage: f(y) # optional - sage.libs.pari sage.libs.singular 2*y """ v = x.list() diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index 5df02b11f3a..cd2ea68f03a 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -386,9 +386,9 @@ def ideal_with_gens_over_base(self, gens): sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage: O = L.equation_order(); O # optional - sage.libs.pari Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari, sage.modules + sage: I.module() # optional - sage.libs.pari sage.modules Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -400,11 +400,11 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari, sage.modules + sage: y in I # optional - sage.libs.pari sage.modules True - sage: y^2 in I # optional - sage.libs.pari, sage.modules + sage: y^2 in I # optional - sage.libs.pari sage.modules False """ F = self.function_field() @@ -439,14 +439,14 @@ def ideal(self, *gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari, sage.modules + sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari sage.modules sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage: S = L.equation_order() # optional - sage.libs.pari - sage: S.ideal(1/y) # optional - sage.libs.pari, sage.modules + sage: S.ideal(1/y) # optional - sage.libs.pari sage.modules Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari, sage.modules + sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari sage.modules Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari, sage.modules + sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.modules True """ if len(gens) == 1: @@ -482,8 +482,8 @@ def basis(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.basis() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.basis() # optional - sage.libs.pari sage.modules (1, y, y^2, y^3) """ return self._basis @@ -497,8 +497,8 @@ def free_module(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.free_module() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.free_module() # optional - sage.libs.pari sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -521,9 +521,9 @@ def coordinate_vector(self, e): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: f = (x + y)^3 # optional - sage.libs.pari, sage.modules - sage: O.coordinate_vector(f) # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: f = (x + y)^3 # optional - sage.libs.pari sage.modules + sage: O.coordinate_vector(f) # optional - sage.libs.pari sage.modules (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e), check=False) @@ -559,14 +559,14 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari sage.modules Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under multiplication and contains the identity element (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari, sage.modules + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication @@ -575,7 +575,7 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari, sage.modules + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -583,9 +583,9 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): Note that 1 does not need to be an element of the basis, as long as it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari, sage.modules + sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari sage.modules Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - sage: O.basis() # optional - sage.libs.pari, sage.modules + sage: O.basis() # optional - sage.libs.pari sage.modules (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) """ def __init__(self, basis, check=True): @@ -596,8 +596,8 @@ def __init__(self, basis, check=True): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite() # optional - sage.libs.pari, sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order_infinite() # optional - sage.libs.pari sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -689,11 +689,11 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order(); O # optional - sage.libs.pari sage.modules Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari, sage.modules + sage: I.module() # optional - sage.libs.pari sage.modules Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] @@ -703,12 +703,12 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari, sage.modules + sage: y in I # optional - sage.libs.pari sage.modules True - sage: y^2 in I # optional - sage.libs.pari, sage.modules + sage: y^2 in I # optional - sage.libs.pari sage.modules False """ F = self.function_field() @@ -780,8 +780,8 @@ def basis(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.basis() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.basis() # optional - sage.libs.pari sage.modules (1, y, y^2, y^3) """ return self._basis @@ -795,8 +795,8 @@ def free_module(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.free_module() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.free_module() # optional - sage.libs.pari sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -1060,10 +1060,10 @@ def _residue_field_global(self, q, name=None): sage: _f = f.numerator() # optional - sage.libs.pari sage: _f.is_irreducible() # optional - sage.libs.pari True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari, sage.modules - sage: K # optional - sage.libs.pari, sage.modules + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules + sage: K # optional - sage.libs.pari sage.modules Finite Field in z6 of size 2^6 - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari, sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules True sage: k. = GF(2) # optional - sage.libs.pari @@ -1075,8 +1075,8 @@ def _residue_field_global(self, q, name=None): sage: _f = f.numerator() # optional - sage.libs.pari sage: _f.is_irreducible() # optional - sage.libs.pari True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari, sage.modules - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari, sage.modules + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules True """ @@ -1228,8 +1228,8 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules """ FunctionFieldMaximalOrder.__init__(self, field, ideal_class) @@ -1323,24 +1323,24 @@ def _element_constructor_(self, f): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: y in O # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: y in O # optional - sage.libs.pari sage.modules True - sage: 1/y in O # optional - sage.libs.pari, sage.modules + sage: 1/y in O # optional - sage.libs.pari sage.modules False - sage: x in O # optional - sage.libs.pari, sage.modules + sage: x in O # optional - sage.libs.pari sage.modules True - sage: 1/x in O # optional - sage.libs.pari, sage.modules + sage: 1/x in O # optional - sage.libs.pari sage.modules False sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: 1 in O # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: 1 in O # optional - sage.libs.pari sage.modules True - sage: y in O # optional - sage.libs.pari, sage.modules + sage: y in O # optional - sage.libs.pari sage.modules False - sage: x*y in O # optional - sage.libs.pari, sage.modules + sage: x*y in O # optional - sage.libs.pari sage.modules True - sage: x^2*y in O # optional - sage.libs.pari, sage.modules + sage: x^2*y in O # optional - sage.libs.pari sage.modules True """ F = self.function_field() @@ -1365,11 +1365,11 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order(); O # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order(); O # optional - sage.libs.pari sage.modules Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari, sage.modules + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari, sage.modules + sage: I.module() # optional - sage.libs.pari sage.modules Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -1380,12 +1380,12 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari, sage.modules + sage: y in I # optional - sage.libs.pari sage.modules True - sage: y^2 in I # optional - sage.libs.pari, sage.modules + sage: y^2 in I # optional - sage.libs.pari sage.modules False """ return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) @@ -1403,14 +1403,14 @@ def _ideal_from_vectors(self, vecs): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: v1 = O.coordinate_vector(x^3+1) # optional - sage.libs.pari, sage.modules - sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari, sage.modules - sage: v1 # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: v1 = O.coordinate_vector(x^3+1) # optional - sage.libs.pari sage.modules + sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari sage.modules + sage: v1 # optional - sage.libs.pari sage.modules (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari, sage.modules + sage: v2 # optional - sage.libs.pari sage.modules (0, 1) - sage: O._ideal_from_vectors([v1,v2]) # optional - sage.libs.pari, sage.modules + sage: O._ideal_from_vectors([v1,v2]) # optional - sage.libs.pari sage.modules Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -1436,16 +1436,16 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: I = O.ideal(y^2) # optional - sage.libs.pari, sage.modules - sage: m = I.basis_matrix() # optional - sage.libs.pari, sage.modules - sage: v1 = m[0] # optional - sage.libs.pari, sage.modules - sage: v2 = m[1] # optional - sage.libs.pari, sage.modules - sage: v1 # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: I = O.ideal(y^2) # optional - sage.libs.pari sage.modules + sage: m = I.basis_matrix() # optional - sage.libs.pari sage.modules + sage: v1 = m[0] # optional - sage.libs.pari sage.modules + sage: v2 = m[1] # optional - sage.libs.pari sage.modules + sage: v1 # optional - sage.libs.pari sage.modules (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari, sage.modules + sage: v2 # optional - sage.libs.pari sage.modules (0, x^3 + 1) - sage: O._ideal_from_vectors([v1,v2]) # indirect doctest # optional - sage.libs.pari, sage.modules + sage: O._ideal_from_vectors([v1,v2]) # indirect doctest # optional - sage.libs.pari sage.modules Ideal (x^3 + 1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -1502,13 +1502,13 @@ def ideal(self, *gens, **kwargs): sage: O = K.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: S = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: S.ideal(1/y) # optional - sage.libs.pari, sage.modules + sage: S = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: S.ideal(1/y) # optional - sage.libs.pari sage.modules Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari, sage.modules + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari sage.modules Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari, sage.modules + sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.modules True sage: K. = FunctionField(QQ); R. = K[] @@ -1543,14 +1543,14 @@ def polynomial(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.polynomial() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.polynomial() # optional - sage.libs.pari sage.modules y^4 + x*y + 4*x + 1 sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular, sage.modules - sage: O.polynomial() # optional - sage.libs.singular, sage.modules + sage: O = L.equation_order() # optional - sage.libs.singular sage.modules + sage: O.polynomial() # optional - sage.libs.singular sage.modules y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -1564,15 +1564,15 @@ def basis(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari, sage.modules - sage: O.basis() # optional - sage.libs.pari, sage.modules + sage: O = L.equation_order() # optional - sage.libs.pari sage.modules + sage: O.basis() # optional - sage.libs.pari sage.modules (1, y, y^2, y^3) sage: K. = FunctionField(QQ) sage: R. = PolynomialRing(K) sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular, sage.modules - sage: O.basis() # optional - sage.libs.singular, sage.modules + sage: O = F.maximal_order() # optional - sage.libs.singular sage.modules + sage: O.basis() # optional - sage.libs.singular sage.modules (1, 1/x^4*y, 1/x^9*y^2, 1/x^13*y^3) """ return self._basis @@ -1587,14 +1587,14 @@ def gen(self, n=0): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O.gen() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O.gen() # optional - sage.libs.pari sage.modules 1 - sage: O.gen(1) # optional - sage.libs.pari, sage.modules + sage: O.gen(1) # optional - sage.libs.pari sage.modules y - sage: O.gen(2) # optional - sage.libs.pari, sage.modules + sage: O.gen(2) # optional - sage.libs.pari sage.modules (1/(x^3 + x^2 + x))*y^2 - sage: O.gen(3) # optional - sage.libs.pari, sage.modules + sage: O.gen(3) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -1612,8 +1612,8 @@ def ngens(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: Oinf.ngens() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: Oinf.ngens() # optional - sage.libs.pari sage.modules 3 """ return len(self._basis) @@ -1626,8 +1626,8 @@ def free_module(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O.free_module() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O.free_module() # optional - sage.libs.pari sage.modules Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 User basis matrix: [1 0 0 0] @@ -1645,17 +1645,17 @@ def coordinate_vector(self, e): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O.coordinate_vector(y) # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O.coordinate_vector(y) # optional - sage.libs.pari sage.modules (0, 1, 0, 0) - sage: O.coordinate_vector(x*y) # optional - sage.libs.pari, sage.modules + sage: O.coordinate_vector(x*y) # optional - sage.libs.pari sage.modules (0, x, 0, 0) sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular, sage.modules - sage: f = (x + y)^3 # optional - sage.libs.singular, sage.modules - sage: O.coordinate_vector(f) # optional - sage.libs.singular, sage.modules + sage: O = L.equation_order() # optional - sage.libs.singular sage.modules + sage: f = (x + y)^3 # optional - sage.libs.singular sage.modules + sage: O.coordinate_vector(f) # optional - sage.libs.singular sage.modules (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e)) @@ -1673,10 +1673,10 @@ def _coordinate_vector(self, e): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O._coordinate_vector(y) # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O._coordinate_vector(y) # optional - sage.libs.pari sage.modules (0, 1, 0, 0) - sage: O._coordinate_vector(x*y) # optional - sage.libs.pari, sage.modules + sage: O._coordinate_vector(x*y) # optional - sage.libs.pari sage.modules (0, x, 0, 0) """ from sage.modules.free_module_element import vector @@ -1693,8 +1693,8 @@ def different(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O.different() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O.different() # optional - sage.libs.pari sage.modules Ideal (y^3 + 2*x) of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1709,8 +1709,8 @@ def codifferent(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O.codifferent() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O.codifferent() # optional - sage.libs.pari sage.modules Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y @@ -1729,8 +1729,8 @@ def _codifferent_matrix(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: O._codifferent_matrix() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: O._codifferent_matrix() # optional - sage.libs.pari sage.modules [ 4 0 0 4*x] [ 0 0 4*x 5*x + 3] [ 0 4*x 5*x + 3 0] @@ -1761,9 +1761,9 @@ def decomposition(self, ideal): sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules - sage: O.decomposition(p) # optional - sage.libs.pari, sage.modules + sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules + sage: O.decomposition(p) # optional - sage.libs.pari sage.modules [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -1888,7 +1888,7 @@ class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: L.maximal_order() # optional - sage.libs.pari, sage.modules + sage: L.maximal_order() # optional - sage.libs.pari sage.modules Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1900,8 +1900,8 @@ def __init__(self, field): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari, sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules + sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules """ FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) @@ -1922,9 +1922,9 @@ def p_radical(self, prime): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.libs.pari sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules - sage: O.p_radical(p) # optional - sage.libs.pari, sage.modules + sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules + sage: O.p_radical(p) # optional - sage.libs.pari sage.modules Ideal (x + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -1984,9 +1984,9 @@ def decomposition(self, ideal): sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari, sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari, sage.modules - sage: O.decomposition(p) # optional - sage.libs.pari, sage.modules + sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules + sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules + sage: O.decomposition(p) # optional - sage.libs.pari sage.modules [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -2242,7 +2242,7 @@ def _repr_(self): sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return "Maximal infinite order of %s"%(self.function_field(),) @@ -2412,12 +2412,12 @@ class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinit sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules + sage: L.maximal_order_infinite() # optional - sage.libs.pari sage.modules Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ def __init__(self, field, category=None): @@ -2428,8 +2428,8 @@ def __init__(self, field, category=None): sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari, sage.modules + sage: O = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules """ FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) @@ -2452,16 +2452,16 @@ def _element_constructor_(self, f): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.basis() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.basis() # optional - sage.libs.pari sage.modules (1, 1/x*y) - sage: 1 in Oinf # optional - sage.libs.pari, sage.modules + sage: 1 in Oinf # optional - sage.libs.pari sage.modules True - sage: 1/x*y in Oinf # optional - sage.libs.pari, sage.modules + sage: 1/x*y in Oinf # optional - sage.libs.pari sage.modules True - sage: x*y in Oinf # optional - sage.libs.pari, sage.modules + sage: x*y in Oinf # optional - sage.libs.pari sage.modules False - sage: 1/x in Oinf # optional - sage.libs.pari, sage.modules + sage: 1/x in Oinf # optional - sage.libs.pari sage.modules True """ F = self.function_field() @@ -2487,16 +2487,16 @@ def basis(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.basis() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.basis() # optional - sage.libs.pari sage.modules (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) :: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.basis() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.basis() # optional - sage.libs.pari sage.modules (1, 1/x*y) """ return self._basis @@ -2511,14 +2511,14 @@ def gen(self, n=0): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.gen() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.gen() # optional - sage.libs.pari sage.modules 1 - sage: Oinf.gen(1) # optional - sage.libs.pari, sage.modules + sage: Oinf.gen(1) # optional - sage.libs.pari sage.modules 1/x^2*y - sage: Oinf.gen(2) # optional - sage.libs.pari, sage.modules + sage: Oinf.gen(2) # optional - sage.libs.pari sage.modules (1/(x^4 + x^3 + x^2))*y^2 - sage: Oinf.gen(3) # optional - sage.libs.pari, sage.modules + sage: Oinf.gen(3) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -2536,8 +2536,8 @@ def ngens(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.ngens() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.ngens() # optional - sage.libs.pari sage.modules 3 """ return len(self._basis) @@ -2554,8 +2554,8 @@ def ideal(self, *gens): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari, sage.modules + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari sage.modules Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -2563,8 +2563,8 @@ def ideal(self, *gens): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari sage.modules Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ if len(gens) == 1: @@ -2586,8 +2586,8 @@ def ideal_with_gens_over_base(self, gens): sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) # optional - sage.libs.pari, sage.modules + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) # optional - sage.libs.pari sage.modules Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -2654,9 +2654,9 @@ def _to_iF(self, I): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: I = Oinf.ideal(y) # optional - sage.libs.pari, sage.modules - sage: Oinf._to_iF(I) # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.modules + sage: Oinf._to_iF(I) # optional - sage.libs.pari sage.modules Ideal (1, 1/x*s) of Maximal order of Function field in s defined by s^2 + x*s + x^3 + x """ @@ -2675,8 +2675,8 @@ def decomposition(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.decomposition() # optional - sage.libs.pari, sage.modules + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.decomposition() # optional - sage.libs.pari sage.modules [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -2686,8 +2686,8 @@ def decomposition(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.decomposition() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.decomposition() # optional - sage.libs.pari sage.modules [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] @@ -2695,8 +2695,8 @@ def decomposition(self): sage: K. = FunctionField(QQ); _. = K[] sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.singular, sage.modules - sage: Oinf.decomposition() # optional - sage.libs.singular, sage.modules + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.singular sage.modules + sage: Oinf.decomposition() # optional - sage.libs.singular sage.modules [(Ideal (1/x^2*y - 1) of Maximal infinite order of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -2706,8 +2706,8 @@ def decomposition(self): sage: K. = FunctionField(QQ); _. = K[] sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.singular, sage.modules - sage: Oinf.decomposition() # optional - sage.libs.singular, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.singular sage.modules + sage: Oinf.decomposition() # optional - sage.libs.singular sage.modules [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] """ @@ -2733,8 +2733,8 @@ def different(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf.different() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf.different() # optional - sage.libs.pari sage.modules Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -2754,8 +2754,8 @@ def _codifferent_matrix(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: Oinf._codifferent_matrix() # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: Oinf._codifferent_matrix() # optional - sage.libs.pari sage.modules [ 0 1/x] [ 1/x 1/x^2] """ @@ -2785,11 +2785,11 @@ def coordinate_vector(self, e): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari, sage.modules - sage: f = 1/y^2 # optional - sage.libs.pari, sage.modules - sage: f in Oinf # optional - sage.libs.pari, sage.modules + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: f = 1/y^2 # optional - sage.libs.pari sage.modules + sage: f in Oinf # optional - sage.libs.pari sage.modules True - sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari, sage.modules + sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari sage.modules ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) """ return self._module.coordinate_vector(self._to_module(e)) diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 6cfc350459e..fe1bbd908bd 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -888,10 +888,10 @@ def _residue_field(self, name=None): :: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular, sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular, sage.rings.number_field - sage: I = O.ideal(x) # optional - sage.libs.singular, sage.rings.number_field - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular, sage.rings.number_field + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field + sage: I = O.ideal(x) # optional - sage.libs.singular sage.rings.number_field + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular sage.rings.number_field [(Algebraic Field, Ring morphism: From: Algebraic Field To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: From fe5faf6cf03734d021e2ae5cdcf9aad95a6936f5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 10 Mar 2023 12:58:01 -0800 Subject: [PATCH 22/54] src/sage/rings/function_field/order.py: Split into modules order_... --- src/sage/rings/function_field/order.py | 2548 +---------------- src/sage/rings/function_field/order_basis.py | 555 ++++ src/sage/rings/function_field/order_global.py | 363 +++ .../rings/function_field/order_polymod.py | 1072 +++++++ .../rings/function_field/order_rational.py | 562 ++++ 5 files changed, 2572 insertions(+), 2528 deletions(-) create mode 100644 src/sage/rings/function_field/order_basis.py create mode 100644 src/sage/rings/function_field/order_global.py create mode 100644 src/sage/rings/function_field/order_polymod.py create mode 100644 src/sage/rings/function_field/order_rational.py diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index cd2ea68f03a..8b19f6ce0c8 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -107,31 +107,22 @@ import sage.rings.abc +from sage.categories.integral_domains import IntegralDomains from sage.misc.cachefunc import cached_method - -from sage.arith.functions import lcm -from sage.arith.misc import GCD as gcd - -from sage.rings.number_field.number_field_base import NumberField -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - +from sage.misc.lazy_import import lazy_import from sage.structure.parent import Parent from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation -from sage.categories.integral_domains import IntegralDomains -from sage.categories.principal_ideal_domains import PrincipalIdealDomains -from sage.categories.euclidean_domains import EuclideanDomains +from .ideal import IdealMonoid, FunctionFieldIdeal -from .ideal import ( - IdealMonoid, - FunctionFieldIdeal, - FunctionFieldIdeal_module, - FunctionFieldIdeal_rational, - FunctionFieldIdeal_polymod, - FunctionFieldIdeal_global, - FunctionFieldIdealInfinite_module, - FunctionFieldIdealInfinite_rational, - FunctionFieldIdealInfinite_polymod) +lazy_import('sage.rings.function_field.order_basis', + ['FunctionFieldOrder_basis', 'FunctionFieldOrderInfinite_basis']) +lazy_import('sage.rings.function_field.order_rational', + ['FunctionFieldMaximalOrder_rational', 'FunctionFieldMaximalOrderInfinite_rational']) +lazy_import('sage.rings.function_field.order_polymod', + ['FunctionFieldMaximalOrder_polymod', 'FunctionFieldMaximalOrderInfinite_polymod']) +lazy_import('sage.rings.function_field.order_global', + ['FunctionFieldMaximalOrder_global']) class FunctionFieldOrder_base(CachedRepresentation, Parent): @@ -247,288 +238,6 @@ def _repr_(self): return "Order in {}".format(self._field) -class FunctionFieldOrder_basis(FunctionFieldOrder): - """ - Order given by a basis over the maximal order of the base field. - - INPUT: - - - ``basis`` -- list of elements of the function field - - - ``check`` -- (default: ``True``) if ``True``, check whether the module - that ``basis`` generates forms an order - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari - Order in Function field in y defined by y^4 + x*y + 4*x + 1 - - The basis only defines an order if the module it generates is closed under - multiplication and contains the identity element:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: y.is_integral() # optional - sage.libs.singular - False - sage: L.order(y) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: the module generated by basis (1, y, y^2, y^3, y^4) must be closed under multiplication - - The basis also has to be linearly independent and of the same rank as the - degree of the function field of its elements (only checked when ``check`` - is ``True``):: - - sage: L.order(L(x)) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: basis (1, x, x^2, x^3, x^4) is not linearly independent - sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: basis (y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x) is not linearly independent - """ - def __init__(self, basis, check=True): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari - """ - if len(basis) == 0: - raise ValueError("basis must have positive length") - - field = basis[0].parent() - if len(basis) != field.degree(): - raise ValueError("length of basis must equal degree of field") - - FunctionFieldOrder.__init__(self, field, ideal_class=FunctionFieldIdeal_module) - - V, from_V, to_V = field.vector_space() - - R = V.base_field().maximal_order() - self._module = V.span([to_V(b) for b in basis], base_ring=R) - - self._from_module= from_V - self._to_module = to_V - self._basis = tuple(basis) - self._ring = field.polynomial_ring() - self._populate_coercion_lists_(coerce_list=[self._ring]) - - if check: - if self._module.rank() != field.degree(): - raise ValueError("basis {} is not linearly independent".format(basis)) - if not to_V(field(1)) in self._module: - raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) - if not all(to_V(a*b) in self._module for a in basis for b in basis): - raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) - - def _element_constructor_(self, f): - """ - Construct an element of this order from ``f``. - - INPUT: - - - ``f`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.maximal_order()._element_constructor_(x) - x - """ - F = self.function_field() - - try: - f = F(f) - except TypeError: - raise TypeError("unable to convert to an element of {}".format(F)) - - V, fr_V, to_V = F.vector_space() - f_vector = to_V(f) - if f_vector not in self._module: - raise TypeError("{} is not an element of {}".format(f_vector, self)) - - return f - - def ideal_with_gens_over_base(self, gens): - """ - Return the fractional ideal with basis ``gens`` over the - maximal order of the base field. - - It is not checked that the ``gens`` really generates an ideal. - - INPUT: - - - ``gens`` -- list of elements of the function field - - EXAMPLES: - - We construct an ideal in a rational function field:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal([y]); I # optional - sage.modules - Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: I*I # optional - sage.modules - Ideal (y^2) of Maximal order of Rational function field in y over Rational Field - - We construct some ideals in a nontrivial function field:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari - Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules - Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari sage.modules - Free module of degree 2 and rank 2 over - Maximal order of Rational function field in x over Finite Field of size 7 - Echelon basis matrix: - [1 0] - [0 1] - - There is no check if the resulting object is really an ideal:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules - Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.modules - True - sage: y^2 in I # optional - sage.libs.pari sage.modules - False - """ - F = self.function_field() - S = F.base_field().maximal_order() - - gens = [F(a) for a in gens] - - V, from_V, to_V = F.vector_space() - M = V.span([to_V(b) for b in gens], base_ring=S) - - return self.ideal_monoid().element_class(self, M) - - def ideal(self, *gens): - """ - Return the fractional ideal generated by the elements in ``gens``. - - INPUT: - - - ``gens`` -- list of generators or an ideal in a ring which - coerces to this order - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O.ideal(y) # optional - sage.modules - Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list # optional - sage.modules - True - - A fractional ideal of a nontrivial extension:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari sage.modules - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: S = L.equation_order() # optional - sage.libs.pari - sage: S.ideal(1/y) # optional - sage.libs.pari sage.modules - Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari sage.modules - Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.modules - True - """ - if len(gens) == 1: - gens = gens[0] - if not isinstance(gens, (list, tuple)): - if isinstance(gens, FunctionFieldIdeal): - gens = gens.gens() - else: - gens = [gens] - K = self.function_field() - - return self.ideal_with_gens_over_base([b*K(g) for b in self.basis() for g in gens]) - - def polynomial(self): - """ - Return the defining polynomial of the function field of which this is an order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.polynomial() # optional - sage.libs.pari - y^4 + x*y + 4*x + 1 - """ - return self._field.polynomial() - - def basis(self): - """ - Return a basis of the order over the maximal order of the base field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.basis() # optional - sage.libs.pari sage.modules - (1, y, y^2, y^3) - """ - return self._basis - - def free_module(self): - """ - Return the free module formed by the basis over the maximal order - of the base function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.free_module() # optional - sage.libs.pari sage.modules - Free module of degree 4 and rank 4 over Maximal order of Rational - function field in x over Finite Field of size 7 - Echelon basis matrix: - [1 0 0 0] - [0 1 0 0] - [0 0 1 0] - [0 0 0 1] - """ - return self._module - - def coordinate_vector(self, e): - """ - Return the coordinates of ``e`` with respect to the basis of the order. - - INPUT: - - - ``e`` -- element of the order or the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: f = (x + y)^3 # optional - sage.libs.pari sage.modules - sage: O.coordinate_vector(f) # optional - sage.libs.pari sage.modules - (x^3, 3*x^2, 3*x, 1) - """ - return self._module.coordinate_vector(self._to_module(e), check=False) - - class FunctionFieldOrderInfinite(FunctionFieldOrder_base): """ Base class for infinite orders in function fields. @@ -543,271 +252,6 @@ def _repr_(self): return "Infinite order in {}".format(self.function_field()) -class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): - """ - Order given by a basis over the infinite maximal order of the base - field. - - INPUT: - - - ``basis`` -- elements of the function field - - - ``check`` -- boolean (default: ``True``); if ``True``, check the basis generates - an order - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari sage.modules - Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - - The basis only defines an order if the module it generates is closed under - multiplication and contains the identity element (only checked when - ``check`` is ``True``):: - - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari sage.modules - Traceback (most recent call last): - ... - ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication - - The basis also has to be linearly independent and of the same rank as the - degree of the function field of its elements (only checked when ``check`` - is ``True``):: - - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari sage.modules - Traceback (most recent call last): - ... - ValueError: The given basis vectors must be linearly independent. - - Note that 1 does not need to be an element of the basis, as long as it is - in the module spanned by it:: - - sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari sage.modules - Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - sage: O.basis() # optional - sage.libs.pari sage.modules - (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) - """ - def __init__(self, basis, check=True): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite() # optional - sage.libs.pari sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules - """ - if len(basis) == 0: - raise ValueError("basis must have positive length") - - field = basis[0].parent() - if len(basis) != field.degree(): - raise ValueError("length of basis must equal degree of field") - - FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_module) - - # function field element f is in this order if and only if - # W.coordinate_vector(to(f)) in M - V, fr, to = field.vector_space() - R = field.base_field().maximal_order_infinite() - W = V.span_of_basis([to(v) for v in basis]) - from sage.modules.free_module import FreeModule - M = FreeModule(R,W.dimension()) - self._basis = tuple(basis) - self._ambient_space = W - self._module = M - - self._ring = field.polynomial_ring() - self._populate_coercion_lists_(coerce_list=[self._ring]) - - if check: - if self._module.rank() != field.degree(): - raise ValueError("basis {} is not linearly independent".format(basis)) - if not W.coordinate_vector(to(field(1))) in self._module: - raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) - if not all(W.coordinate_vector(to(a*b)) in self._module for a in basis for b in basis): - raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) - - def _element_constructor_(self, f): - """ - Construct an element of this order. - - INPUT: - - - ``f`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O(x) - x - sage: O(1/x) - Traceback (most recent call last): - ... - TypeError: 1/x is not an element of Maximal order of Rational function field in x over Rational Field - """ - F = self.function_field() - try: - f = F(f) - except TypeError: - raise TypeError("unable to convert to an element of {}".format(F)) - - V, fr_V, to_V = F.vector_space() - W = self._ambient_space - if not W.coordinate_vector(to_V(f)) in self._module: - raise TypeError("{} is not an element of {}".format(f, self)) - - return f - - def ideal_with_gens_over_base(self, gens): - """ - Return the fractional ideal with basis ``gens`` over the - maximal order of the base field. - - It is not checked that ``gens`` really generates an ideal. - - INPUT: - - - ``gens`` -- list of elements that are a basis for the ideal over the - maximal order of the base field - - EXAMPLES: - - We construct an ideal in a rational function field:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal([y]); I - Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: I*I - Ideal (y^2) of Maximal order of Rational function field in y over Rational Field - - We construct some ideals in a nontrivial function field:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari sage.modules - Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules - Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari sage.modules - Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 - Echelon basis matrix: - [1 0] - [0 1] - - There is no check if the resulting object is really an ideal:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules - Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.modules - True - sage: y^2 in I # optional - sage.libs.pari sage.modules - False - """ - F = self.function_field() - S = F.base_field().maximal_order_infinite() - - gens = [F(a) for a in gens] - - V, from_V, to_V = F.vector_space() - M = V.span([to_V(b) for b in gens], base_ring=S) # not work - - return self.ideal_monoid().element_class(self, M) - - def ideal(self, *gens): - """ - Return the fractional ideal generated by the elements in ``gens``. - - INPUT: - - - ``gens`` -- list of generators or an ideal in a ring which coerces - to this order - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O.ideal(y) - Ideal (y) of Maximal order of Rational function field in y over Rational Field - sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list - True - - A fractional ideal of a nontrivial extension:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: O = K.maximal_order_infinite() - sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) # optional - sage.libs.singular - """ - if len(gens) == 1: - gens = gens[0] - if not isinstance(gens, (list, tuple)): - if isinstance(gens, FunctionFieldIdeal): - gens = gens.gens() - else: - gens = [gens] - K = self.function_field() - - return self.ideal_with_gens_over_base([b*K(g) for b in self.basis() for g in gens]) - - def polynomial(self): - """ - Return the defining polynomial of the function field of which this is an order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.polynomial() # optional - sage.libs.pari - y^4 + x*y + 4*x + 1 - """ - return self._field.polynomial() - - def basis(self): - """ - Return a basis of this order over the maximal order of the base field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.basis() # optional - sage.libs.pari sage.modules - (1, y, y^2, y^3) - """ - return self._basis - - def free_module(self): - """ - Return the free module formed by the basis over the maximal order of - the base field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.free_module() # optional - sage.libs.pari sage.modules - Free module of degree 4 and rank 4 over Maximal order of Rational - function field in x over Finite Field of size 7 - Echelon basis matrix: - [1 0 0 0] - [0 1 0 0] - [0 0 1 0] - [0 0 0 1] - """ - return self._module - - class FunctionFieldMaximalOrder(UniqueRepresentation, FunctionFieldOrder): """ Base class of maximal orders of function fields. @@ -824,1972 +268,20 @@ def _repr_(self): return "Maximal order of %s"%(self.function_field(),) -class FunctionFieldMaximalOrder_rational(FunctionFieldMaximalOrder): +class FunctionFieldMaximalOrderInfinite(FunctionFieldMaximalOrder, FunctionFieldOrderInfinite): """ - Maximal orders of rational function fields. - - INPUT: - - - ``field`` -- a function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari - Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order(); R # optional - sage.libs.pari - Maximal order of Rational function field in t over Finite Field of size 19 + Base class of maximal infinite orders of function fields. """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') - """ - FunctionFieldMaximalOrder.__init__(self, field, ideal_class=FunctionFieldIdeal_rational, - category=EuclideanDomains()) - - self._populate_coercion_lists_(coerce_list=[field._ring]) - - self._ring = field._ring - self._gen = self(self._ring.gen()) - self._basis = (self.one(),) - - def _element_constructor_(self, f): - """ - Make ``f`` a function field element of this order. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O._element_constructor_(y) - y - sage: O._element_constructor_(1/y) - Traceback (most recent call last): - ... - TypeError: 1/y is not an element of Maximal order of Rational function field in y over Rational Field - """ - F = self.function_field() - try: - f = F(f) - except TypeError: - raise TypeError("unable to convert to an element of {}".format(F)) - - if not f.denominator() in self.function_field().constant_base_field(): - raise TypeError("%r is not an element of %r"%(f,self)) - - return f - - def ideal_with_gens_over_base(self, gens): - """ - Return the fractional ideal with generators ``gens``. - - INPUT: - - - ``gens`` -- elements of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) # optional - sage.libs.singular - Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - """ - return self.ideal(gens) - - def _residue_field(self, ideal, name=None): + def _repr_(self): """ - Return a field isomorphic to the residue field at the prime ideal. - - The residue field is by definition `k[x]/q` where `q` is the irreducible - polynomial generating the prime ideal and `k` is the constant base field. - - INPUT: - - - ``ideal`` -- prime ideal of the order - - - ``name`` -- string; name of the generator of the residue field - - OUTPUT: - - - a field isomorphic to the residue field - - - a morphism from the field to `k[x]` via the residue field - - - a morphism from `k[x]` to the field via the residue field - EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari - Finite Field in z2 of size 2^2 - sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari - [True, True, True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari - [True, True, True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari - True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari - True - sage: to_R(e1).parent() is R # optional - sage.libs.pari - True - sage: to_R(e2).parent() is R # optional - sage.libs.pari - True - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + 1) # optional - sage.libs.pari - sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari - Finite Field of size 2 - sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari - [True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari - [True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari - True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari - True - sage: to_R(e1).parent() is R # optional - sage.libs.pari - True - sage: to_R(e2).parent() is R # optional - sage.libs.pari - True - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: I = O.ideal(x^2 + x + 1) - sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.rings.number_field - sage: R # optional - sage.rings.number_field - Number Field in a with defining polynomial x^2 + x + 1 - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.rings.number_field - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.rings.number_field - True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.rings.number_field - True - sage: to_R(e1).parent() is R # optional - sage.rings.number_field - True - sage: to_R(e2).parent() is R # optional - sage.rings.number_field - True - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: I = O.ideal(x + 1) - sage: R, fr_R, to_R = O._residue_field(I) - sage: R - Rational Field - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) - True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) - True - sage: to_R(e1).parent() is R - True - sage: to_R(e2).parent() is R - True - """ - F = self.function_field() - K = F.constant_base_field() - - q = ideal.gen().element().numerator() - - if F.is_global(): - R, _from_R, _to_R = self._residue_field_global(q, name=name) - elif isinstance(K, (NumberField, sage.rings.abc.AlgebraicField)): - if name is None: - name = 'a' - if q.degree() == 1: - R = K - _from_R = lambda e: e - _to_R = lambda e: R(e % q) - else: - R = K.extension(q, names=name) - _from_R = lambda e: self._ring(list(R(e))) - _to_R = lambda e: (e % q)(R.gen(0)) - else: - raise NotImplementedError - - def from_R(e): - return F(_from_R(e)) - - def to_R(f): - return _to_R(f.numerator()) - - return R, from_R, to_R + sage: FunctionField(QQ,'y').maximal_order_infinite() + Maximal infinite order of Rational function field in y over Rational Field - def _residue_field_global(self, q, name=None): - """ - Return a finite field isomorphic to the residue field at q. - - This method assumes a global rational function field, that is, - the constant base field is a finite field. - - INPUT: - - - ``q`` -- irreducible polynomial - - - ``name`` -- string; name of the generator of the extension field - - OUTPUT: - - - a finite field - - - a function that outputs a polynomial lifting a finite field element - - - a function that outputs a finite field element for a polynomial - - The residue field is by definition `k[x]/q` where `k` is the base field. - - EXAMPLES:: - - sage: k. = GF(4) # optional - sage.libs.pari - sage: F. = FunctionField(k) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O._ring # optional - sage.libs.pari - Univariate Polynomial Ring in x over Finite Field in a of size 2^2 - sage: f = x^3 + x + 1 # optional - sage.libs.pari - sage: _f = f.numerator() # optional - sage.libs.pari - sage: _f.is_irreducible() # optional - sage.libs.pari - True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules - sage: K # optional - sage.libs.pari sage.modules - Finite Field in z6 of size 2^6 - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules - True - - sage: k. = GF(2) # optional - sage.libs.pari - sage: F. = FunctionField(k) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O._ring # optional - sage.libs.pari - Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: f = x^3 + x + 1 # optional - sage.libs.pari - sage: _f = f.numerator() # optional - sage.libs.pari - sage: _f.is_irreducible() # optional - sage.libs.pari - True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules - True - - """ - # polynomial ring over the base field - R = self._ring - - # base field of extension degree r over the prime field - k = R.base_ring() - a = k.gen() - r = k.degree() - - # extend the base field to a field of degree r*s over the - # prime field - s = q.degree() - K,sigma = k.extension(s, map=True, name=name) - - # find a root beta in K satisfying the irreducible q - S = K['X'] - beta = S([sigma(c) for c in q.list()]).roots()[0][0] - - # V is a vector space over the prime subfield of k of degree r*s - V = K.vector_space(map=False) - - w = K.one() - beta_pow = [] - for i in range(s): - beta_pow.append(w) - w *= beta - - w = K.one() - sigma_a = sigma(a) - sigma_a_pow = [] - for i in range(r): - sigma_a_pow.append(w) - w *= sigma_a - - basis = [V(sap * bp) for bp in beta_pow for sap in sigma_a_pow] - W = V.span_of_basis(basis) - - def to_K(f): - coeffs = (f % q).list() - return sum((sigma(c) * beta_pow[i] for i, c in enumerate(coeffs)), K.zero()) - - if r == 1: # take care of the prime field case - def fr_K(g): - co = W.coordinates(V(g), check=False) - return R([k(co[j]) for j in range(s)]) - else: - def fr_K(g): - co = W.coordinates(V(g), check=False) - return R([k(co[i:i+r]) for i in range(0, r*s, r)]) - - return K, fr_K, to_K - - def basis(self): - """ - Return the basis (=1) of the order as a module over the polynomial ring. - - EXAMPLES:: - - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari - (1,) - """ - return self._basis - - def gen(self, n=0): - """ - Return the ``n``-th generator of the order. Since there is only one generator ``n`` must be 0. - - EXAMPLES:: - - sage: O = FunctionField(QQ,'y').maximal_order() - sage: O.gen() - y - sage: O.gen(1) - Traceback (most recent call last): - ... - IndexError: there is only one generator - """ - if n != 0: - raise IndexError("there is only one generator") - return self._gen - - def ngens(self): - """ - Return 1 the number of generators of the order. - - EXAMPLES:: - - sage: FunctionField(QQ,'y').maximal_order().ngens() - 1 - """ - return 1 - - def ideal(self, *gens): - """ - Return the fractional ideal generated by ``gens``. - - INPUT: - - - ``gens`` -- elements of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O.ideal(x) - Ideal (x) of Maximal order of Rational function field in x over Rational Field - sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list - True - sage: O.ideal(x^3+1,x^3+6) - Ideal (1) of Maximal order of Rational function field in x over Rational Field - sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I - Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field - sage: O.ideal(I) - Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field - """ - if len(gens) == 1: - gens = gens[0] - if not isinstance(gens, (list, tuple)): - if isinstance(gens, FunctionFieldIdeal): - gens = gens.gens() - else: - gens = (gens,) - K = self.function_field() - gens = [K(e) for e in gens if e != 0] - if len(gens) == 0: - gen = K(0) - else: - d = lcm([c.denominator() for c in gens]).monic() - g = gcd([(d*c).numerator() for c in gens]).monic() - gen = K(g/d) - - return self.ideal_monoid().element_class(self, gen) - - -class FunctionFieldMaximalOrder_polymod(FunctionFieldMaximalOrder): - """ - Maximal orders of extensions of function fields. - """ - - def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules - """ - FunctionFieldMaximalOrder.__init__(self, field, ideal_class) - - from sage.modules.free_module_element import vector - from .function_field import FunctionField_integral - - if isinstance(field, FunctionField_integral): - basis = field._maximal_order_basis() - else: - model, from_model, to_model = field.monic_integral_model('z') - basis = [from_model(g) for g in model._maximal_order_basis()] - - V, fr, to = field.vector_space() - R = field.base_field().maximal_order() - - # This module is over R, but linear algebra over R (MaximalOrder) - # is not well supported in Sage. So we keep it as a vector space - # over rational function field. - self._module = V.span_of_basis([to(b) for b in basis]) - self._module_base_ring = R - self._basis = tuple(basis) - self._from_module = fr - self._to_module = to - - # multiplication table (lower triangular) - n = len(basis) - self._mtable = [] - for i in range(n): - row = [] - for j in range(n): - row.append(self._coordinate_vector(basis[i] * basis[j])) - self._mtable.append(row) - - zero = vector(R._ring, n * [0]) - - def mul_vecs(f, g): - s = zero - for i in range(n): - if f[i].is_zero(): - continue - for j in range(n): - if g[j].is_zero(): - continue - s += f[i] * g[j] * self._mtable[i][j] - return s - self._mul_vecs = mul_vecs - - # We prepare for using Kummer's theorem to decompose primes. Note - # that Kummer's theorem applies to most places. Here we find - # places for which the theorem does not apply. - - # this element is integral over k[x] and a generator of the field. - for gen in basis: - phi = gen.minimal_polynomial() - if phi.degree() == n: - break - - assert phi.degree() == n - - gen_vec = self._coordinate_vector(gen) - g = gen_vec.parent().gen(0) # x - gen_vec_pow = [g] - for i in range(n): - g = mul_vecs(g, gen_vec) - gen_vec_pow.append(g) - - # find places where {1,gen,...,gen^(n-1)} is not integral basis - W = V.span_of_basis([to(gen ** i) for i in range(phi.degree())]) - - supp = [] - for g in basis: - for c in W.coordinate_vector(to(g), check=False): - if not c.is_zero(): - supp += [f for f,_ in c.denominator().factor()] - supp = set(supp) - - self._kummer_gen = gen - self._kummer_gen_vec_pow = gen_vec_pow - self._kummer_polynomial = phi - self._kummer_places = supp - - def _element_constructor_(self, f): - """ - Construct an element of this order from ``f``. - - INPUT: - - - ``f`` -- element convertible to the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: y in O # optional - sage.libs.pari sage.modules - True - sage: 1/y in O # optional - sage.libs.pari sage.modules - False - sage: x in O # optional - sage.libs.pari sage.modules - True - sage: 1/x in O # optional - sage.libs.pari sage.modules - False - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: 1 in O # optional - sage.libs.pari sage.modules - True - sage: y in O # optional - sage.libs.pari sage.modules - False - sage: x*y in O # optional - sage.libs.pari sage.modules - True - sage: x^2*y in O # optional - sage.libs.pari sage.modules - True - """ - F = self.function_field() - f = F(f) - # check if f is in this order - if not all(e in self._module_base_ring for e in self.coordinate_vector(f)): - raise TypeError( "{} is not an element of {}".format(f, self) ) - - return f - - def ideal_with_gens_over_base(self, gens): - """ - Return the fractional ideal with basis ``gens`` over the - maximal order of the base field. - - INPUT: - - - ``gens`` -- list of elements that generates the ideal over the - maximal order of the base field - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order(); O # optional - sage.libs.pari sage.modules - Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.modules - Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari sage.modules - Free module of degree 2 and rank 2 over - Maximal order of Rational function field in x over Finite Field of size 7 - Echelon basis matrix: - [1 0] - [0 1] - - There is no check if the resulting object is really an ideal:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.modules - Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.modules - True - sage: y^2 in I # optional - sage.libs.pari sage.modules - False - """ - return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) - - def _ideal_from_vectors(self, vecs): - """ - Return an ideal generated as a module by vectors over rational function - field. - - INPUT: - - - ``vec`` -- list of vectors - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: v1 = O.coordinate_vector(x^3+1) # optional - sage.libs.pari sage.modules - sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari sage.modules - sage: v1 # optional - sage.libs.pari sage.modules - (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari sage.modules - (0, 1) - sage: O._ideal_from_vectors([v1,v2]) # optional - sage.libs.pari sage.modules - Ideal (y) of Maximal order of Function field in y - defined by y^2 + 6*x^3 + 6 - """ - d = lcm([v.denominator() for v in vecs]) - vecs = [[(d*c).numerator() for c in v] for v in vecs] - return self._ideal_from_vectors_and_denominator(vecs, d, check=False) - - def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): - """ - Return an ideal generated as a module by vectors divided by ``d`` over - the polynomial ring underlying the rational function field. - - INPUT: - - - ``vec`` -- list of vectors over the polynomial ring - - - ``d`` -- (default: 1) a nonzero element of the polynomial ring - - - ``check`` -- boolean (default: ``True``); if ``True``, compute the real - denominator of the vectors, possibly different from ``d``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: I = O.ideal(y^2) # optional - sage.libs.pari sage.modules - sage: m = I.basis_matrix() # optional - sage.libs.pari sage.modules - sage: v1 = m[0] # optional - sage.libs.pari sage.modules - sage: v2 = m[1] # optional - sage.libs.pari sage.modules - sage: v1 # optional - sage.libs.pari sage.modules - (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari sage.modules - (0, x^3 + 1) - sage: O._ideal_from_vectors([v1,v2]) # indirect doctest # optional - sage.libs.pari sage.modules - Ideal (x^3 + 1) of Maximal order of Function field in y - defined by y^2 + 6*x^3 + 6 - """ - from sage.matrix.constructor import matrix - from .hermite_form_polynomial import reversed_hermite_form - - R = self._module_base_ring._ring - - d = R(d) # make it sure that d is in the polynomial ring - - if check and not d.is_one(): # check if d is true denominator - M = [] - g = d - for v in vecs: - for c in v: - g = g.gcd(c) - if g.is_one(): - break - else: - M += list(v) - continue # for v in vecs - mat = matrix(R, vecs) - break - else: - d = d // g - mat = matrix(R, len(vecs), [c // g for c in M]) - else: - mat = matrix(R, vecs) - - # IMPORTANT: make it sure that pivot polynomials monic - # so that we get a unique hnf. Here the hermite form - # algorithm also makes the pivots monic. - - # compute the reversed hermite form with zero rows deleted - reversed_hermite_form(mat) - i = 0 - while i < mat.nrows() and mat.row(i).is_zero(): - i += 1 - hnf = mat[i:] # remove zero rows - - return self.ideal_monoid().element_class(self, hnf, d) - - def ideal(self, *gens, **kwargs): - """ - Return the fractional ideal generated by the elements in ``gens``. - - INPUT: - - - ``gens`` -- list of generators - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: S = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: S.ideal(1/y) # optional - sage.libs.pari sage.modules - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field - in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari sage.modules - Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.modules - True - - sage: K. = FunctionField(QQ); R. = K[] - sage: O = K.maximal_order() - sage: I = O.ideal(x^2 - 4) - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.modules - sage: S = L.maximal_order() # optional - sage.modules - sage: S.ideal(1/y) # optional - sage.modules - Ideal ((1/(x^3 + 1))*y) of - Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I2 = S.ideal(x^2-4); I2 # optional - sage.modules - Ideal (x^2 - 4) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I2 == S.ideal(I) # optional - sage.modules - True - """ - if len(gens) == 1: - gens = gens[0] - if not isinstance(gens, (list, tuple)): - if isinstance(gens, FunctionFieldIdeal): - gens = gens.gens() - else: - gens = (gens,) - F = self.function_field() - mgens = [b*F(g) for g in gens for b in self.basis()] - return self.ideal_with_gens_over_base(mgens) - - def polynomial(self): - """ - Return the defining polynomial of the function field of which this is an order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.polynomial() # optional - sage.libs.pari sage.modules - y^4 + x*y + 4*x + 1 - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular sage.modules - sage: O.polynomial() # optional - sage.libs.singular sage.modules - y^4 + x*y + 4*x + 1 - """ - return self._field.polynomial() - - def basis(self): - """ - Return a basis of the order over the maximal order of the base function - field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari sage.modules - sage: O.basis() # optional - sage.libs.pari sage.modules - (1, y, y^2, y^3) - - sage: K. = FunctionField(QQ) - sage: R. = PolynomialRing(K) - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular sage.modules - sage: O.basis() # optional - sage.libs.singular sage.modules - (1, 1/x^4*y, 1/x^9*y^2, 1/x^13*y^3) - """ - return self._basis - - def gen(self, n=0): - """ - Return the ``n``-th generator of the order. - - The basis elements of the order are generators. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O.gen() # optional - sage.libs.pari sage.modules - 1 - sage: O.gen(1) # optional - sage.libs.pari sage.modules - y - sage: O.gen(2) # optional - sage.libs.pari sage.modules - (1/(x^3 + x^2 + x))*y^2 - sage: O.gen(3) # optional - sage.libs.pari sage.modules - Traceback (most recent call last): - ... - IndexError: there are only 3 generators - """ - if not ( n >= 0 and n < self.ngens() ): - raise IndexError("there are only {} generators".format(self.ngens())) - - return self._basis[n] - - def ngens(self): - """ - Return the number of generators of the order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: Oinf.ngens() # optional - sage.libs.pari sage.modules - 3 - """ - return len(self._basis) - - def free_module(self): - """ - Return the free module formed by the basis over the maximal order of the base field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O.free_module() # optional - sage.libs.pari sage.modules - Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 - User basis matrix: - [1 0 0 0] - [0 1 0 0] - [0 0 1 0] - [0 0 0 1] - """ - return self._module.change_ring(self._module_base_ring) - - def coordinate_vector(self, e): - """ - Return the coordinates of ``e`` with respect to the basis of this order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O.coordinate_vector(y) # optional - sage.libs.pari sage.modules - (0, 1, 0, 0) - sage: O.coordinate_vector(x*y) # optional - sage.libs.pari sage.modules - (0, x, 0, 0) - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular sage.modules - sage: f = (x + y)^3 # optional - sage.libs.singular sage.modules - sage: O.coordinate_vector(f) # optional - sage.libs.singular sage.modules - (x^3, 3*x^2, 3*x, 1) - """ - return self._module.coordinate_vector(self._to_module(e)) - - def _coordinate_vector(self, e): - """ - Return the coordinate vector of ``e`` with respect to the basis - of the order. - - Assuming ``e`` is in the maximal order, the coordinates are given - as univariate polynomials in the underlying ring of the maximal - order of the rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O._coordinate_vector(y) # optional - sage.libs.pari sage.modules - (0, 1, 0, 0) - sage: O._coordinate_vector(x*y) # optional - sage.libs.pari sage.modules - (0, x, 0, 0) - """ - from sage.modules.free_module_element import vector - - v = self._module.coordinate_vector(self._to_module(e), check=False) - return vector([c.numerator() for c in v]) - - @cached_method - def different(self): - """ - Return the different ideal of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O.different() # optional - sage.libs.pari sage.modules - Ideal (y^3 + 2*x) - of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 - """ - return ~self.codifferent() - - @cached_method - def codifferent(self): - """ - Return the codifferent ideal of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O.codifferent() # optional - sage.libs.pari sage.modules - Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 - + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 - + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y - + 6*x/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4)) of Maximal order of Function field - in y defined by y^4 + x*y + 4*x + 1 - """ - T = self._codifferent_matrix() - return self._ideal_from_vectors(T.inverse().columns()) - - @cached_method - def _codifferent_matrix(self): - """ - Return the matrix `T` defined in Proposition 4.8.19 of [Coh1993]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: O._codifferent_matrix() # optional - sage.libs.pari sage.modules - [ 4 0 0 4*x] - [ 0 0 4*x 5*x + 3] - [ 0 4*x 5*x + 3 0] - [ 4*x 5*x + 3 0 3*x^2] - """ - from sage.matrix.constructor import matrix - - rows = [] - for u in self.basis(): - row = [] - for v in self.basis(): - row.append((u*v).trace()) - rows.append(row) - T = matrix(rows) - return T - - @cached_method - def decomposition(self, ideal): - """ - Return the decomposition of the prime ideal. - - INPUT: - - - ``ideal`` -- prime ideal of the base maximal order - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules - sage: O.decomposition(p) # optional - sage.libs.pari sage.modules - [(Ideal (x + 1, y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), - (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - - ALGORITHM: - - In principle, we're trying to compute a primary decomposition - of the extension of ``ideal`` in ``self`` (an order, and therefore - a ring). However, while we have primary decomposition methods - for polynomial rings, we lack any such method for an order. - Therefore, we construct ``self`` mod ``ideal`` as a - finite-dimensional algebra, a construct for which we do - support primary decomposition. - - See :trac:`28094` and https://github.com/sagemath/sage/files/10659303/decomposition.pdf.gz - - .. TODO:: - - Use Kummer's theorem to shortcut this code if possible, like as - done in :meth:`FunctionFieldMaximalOrder_global.decomposition()` - - """ - from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - F = self.function_field() - n = F.degree() - - # Base rational function field - K = self.function_field().base_field() - - # Univariate polynomial ring isomorphic to the maximal order of K - o = PolynomialRing(K.constant_field(), K.gen()) - - # Prime ideal in o defined by the generator of ideal in the maximal - # order of K - p = o(ideal.gen().numerator()) - - # Residue field k = o mod p - k = o.quo(p) - - # Given an element of the function field expressed as a K-vector times - # the basis of this order, construct the n n-by-n matrices that show - # how to multiply by each of the basis elements. - matrices = [matrix(o, [self.coordinate_vector(b1*b2) for b1 in self.basis()]) - for b2 in self.basis()] - - # Let O denote the maximal order self. When reduced modulo p, - # matrices_reduced give the multiplication matrices used to form the - # algebra O mod pO. - matrices_reduced = list(map(lambda M: M.mod(p), matrices)) - A = FiniteDimensionalAlgebra(k, matrices_reduced) - - # Each prime ideal of the algebra A corresponds to a prime ideal of O, - # and since the algebra is an Artinian ring, all of its prime ideals - # are maximal [stacks 00JA]. Thus, we find all of our factors by - # iterating over the algebra's maximal ideals. - factors = [] - for q in A.maximal_ideals(): - if q == A.zero_ideal(): - # The zero ideal is the unique maximal ideal, which means that - # A is a field, and the ideal itself is a prime ideal. - P = self.ideal(p) - - P.is_prime.set_cache(True) - P._prime_below = ideal - P._relative_degree = n - P._ramification_index = 1 - P._beta = [1] + [0]*(n-1) - else: - Q = q.basis_matrix().apply_map(lambda e: e.lift()) - P = self.ideal(p, *Q*vector(self.basis())) - - # Now we compute an element beta in O but not in pO such that - # beta*P in pO. - - # Since beta is in k[x]-module O, we keep beta as a vector - # in k[x] with respect to the basis of O. As long as at least - # one element in this vector is not divisible by p, beta will - # not be in pO. To ensure that beta*P is in pO, multiplying - # beta by each of P's generators must produce a vector whose - # elements are multiples of p. We can ensure that all this - # occurs by constructing a matrix in k, and finding a non-zero - # vector in the kernel of the matrix. - - m =[] - for g in q.basis_matrix(): - m.extend(matrix([g * mr for mr in matrices_reduced]).columns()) - beta = [c.lift() for c in matrix(m).right_kernel().basis()[0]] - - r = q - index = 1 - while True: - rq = r*q - if rq == r: - break - r = rq - index = index + 1 - - P.is_prime.set_cache(True) - P._prime_below = ideal - P._relative_degree = n - q.basis_matrix().nrows() - P._ramification_index = index - P._beta = beta - - factors.append((P, P._relative_degree, P._ramification_index)) - - return factors - - -class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): - """ - Maximal orders of global function fields. - - INPUT: - - - ``field`` -- function field to which this maximal order belongs - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: L.maximal_order() # optional - sage.libs.pari sage.modules - Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 - """ - - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules - """ - FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) - - @cached_method - def p_radical(self, prime): - """ - Return the ``prime``-radical of the maximal order. - - INPUT: - - - ``prime`` -- prime ideal of the maximal order of the base - rational function field - - The algorithm is outlined in Section 6.1.3 of [Coh1993]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules - sage: O.p_radical(p) # optional - sage.libs.pari sage.modules - Ideal (x + 1) of Maximal order of Function field in y - defined by y^3 + x^6 + x^4 + x^2 - """ - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - g = prime.gens()[0] - - if not (g.denominator() == 1 and g.numerator().is_irreducible()): - raise ValueError('not a prime ideal') - - F = self.function_field() - n = F.degree() - o = prime.ring() - p = g.numerator() - - # Fp is isomorphic to the residue field o/p - Fp, fr_Fp, to_Fp = o._residue_field_global(p) - - # exp = q^j should be at least extension degree where q is - # the order of the residue field o/p - q = F.constant_base_field().order()**p.degree() - exp = q - while exp <= F.degree(): - exp = exp**q - - # radical equals to the kernel of the map x |-> x^exp - mat = [] - for g in self.basis(): - v = [to_Fp(c) for c in self._coordinate_vector(g**exp)] - mat.append(v) - mat = matrix(Fp, mat) - ker = mat.kernel() - - # construct module generators of the p-radical - vecs = [] - for i in range(n): - v = vector([p if j == i else 0 for j in range(n)]) - vecs.append(v) - for b in ker.basis(): - v = vector([fr_Fp(c) for c in b]) - vecs.append(v) - - return self._ideal_from_vectors(vecs) - - @cached_method - def decomposition(self, ideal): - """ - Return the decomposition of the prime ideal. - - INPUT: - - - ``ideal`` -- prime ideal of the base maximal order - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari sage.modules - sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage.modules - sage: O.decomposition(p) # optional - sage.libs.pari sage.modules - [(Ideal (x + 1, y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), - (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - """ - from sage.matrix.constructor import matrix - - F = self.function_field() - n = F.degree() - - p = ideal.gen().numerator() - o = ideal.ring() - - # Fp is isomorphic to the residue field o/p - Fp, fr, to = o._residue_field_global(p) - P,X = Fp['X'].objgen() - - V = Fp**n # Ob = O/pO - - mtable = [] - for i in range(n): - row = [] - for j in range(n): - row.append( V([to(e) for e in self._mtable[i][j]]) ) - mtable.append(row) - - if p not in self._kummer_places: - ##################################### - # Decomposition by Kummer's theorem # - ##################################### - # gen is self._kummer_gen - gen_vec_pow = self._kummer_gen_vec_pow - mul_vecs = self._mul_vecs - - f = self._kummer_polynomial - fp = P([to(c.numerator()) for c in f.list()]) - decomposition = [] - for q, exp in fp.factor(): - # construct O.ideal([p,q(gen)]) - gen_vecs = list(matrix.diagonal(n * [p])) - c = q.list() - - # q(gen) in vector form - qgen = sum(fr(c[i]) * gen_vec_pow[i] for i in range(len(c))) - - I = matrix.identity(o._ring, n) - for i in range(n): - gen_vecs.append(mul_vecs(qgen,I[i])) - prime = self._ideal_from_vectors_and_denominator(gen_vecs) - - # Compute an element beta in O but not in pO. How to find beta - # is explained in Section 4.8.3 of [Coh1993]. We keep beta - # as a vector over k[x] with respect to the basis of O. - - # p and qgen generates the prime; modulo pO, qgenb generates the prime - qgenb = [to(qgen[i]) for i in range(n)] - m =[] - for i in range(n): - m.append(sum(qgenb[j] * mtable[i][j] for j in range(n))) - beta = [fr(coeff) for coeff in matrix(m).left_kernel().basis()[0]] - - prime.is_prime.set_cache(True) - prime._prime_below = ideal - prime._relative_degree = q.degree() - prime._ramification_index = exp - prime._beta = beta - - prime._kummer_form = (p, qgen) - - decomposition.append((prime, q.degree(), exp)) - else: - ############################# - # Buchman-Lenstra algorithm # - ############################# - from sage.matrix.special import block_matrix - from sage.modules.free_module_element import vector - - pO = self.ideal(p) - Ip = self.p_radical(ideal) - Ob = matrix.identity(Fp, n) - - def bar(I): # transfer to O/pO - m = [] - for v in I._hnf: - m.append([to(e) for e in v]) - h = matrix(m).echelon_form() - return cut_last_zero_rows(h) - - def liftb(Ib): - m = [vector([fr(e) for e in v]) for v in Ib] - m += [v for v in pO._hnf] - return self._ideal_from_vectors_and_denominator(m,1) - - def cut_last_zero_rows(h): - i = h.nrows() - while i > 0 and h.row(i-1).is_zero(): - i -= 1 - return h[:i] - - def mul_vec(v1,v2): - s = 0 - for i in range(n): - for j in range(n): - s += v1[i] * v2[j] * mtable[i][j] - return s - - def pow(v, r): # r > 0 - m = v - while r > 1: - m = mul_vec(m,v) - r -= 1 - return m - - # Algorithm 6.2.7 of [Coh1993] - def div(Ib, Jb): - # compute a basis of Jb/Ib - sJb = Jb.row_space() - sIb = Ib.row_space() - sJbsIb,proj_sJbsIb,lift_sJbsIb = sJb.quotient_abstract(sIb) - supplement_basis = [lift_sJbsIb(v) for v in sJbsIb.basis()] - - m = [] - for b in V.gens(): # basis of Ob = O/pO - b_row = [] # row vector representation of the map a -> a*b - for a in supplement_basis: - b_row += lift_sJbsIb(proj_sJbsIb( mul_vec(a,b) )) - m.append(b_row) - return matrix(Fp,n,m).left_kernel().basis_matrix() - - # Algorithm 6.2.5 of [Coh1993] - def mul(Ib, Jb): - m = [] - for v1 in Ib: - for v2 in Jb: - m.append(mul_vec(v1,v2)) - h = matrix(m).echelon_form() - return cut_last_zero_rows(h) - - def add(Ib,Jb): - m = block_matrix([[Ib], [Jb]]) - h = m.echelon_form() - return cut_last_zero_rows(h) - - # K_1, K_2, ... - Lb = IpOb = bar(Ip+pO) - Kb = [Lb] - while not Lb.is_zero(): - Lb = mul(Lb,IpOb) - Kb.append(Lb) - - # J_1, J_2, ... - Jb =[Kb[0]] + [div(Kb[j],Kb[j-1]) for j in range(1,len(Kb))] - - # H_1, H_2, ... - Hb = [div(Jb[j],Jb[j+1]) for j in range(len(Jb)-1)] + [Jb[-1]] - - q = Fp.order() - - def split(h): - # VsW represents O/H as a vector space - W = h.row_space() # H/pO - VsW,to_VsW,lift_to_V = V.quotient_abstract(W) - - # compute the space K of elements in O/H that satisfy a^q-a=0 - l = [lift_to_V(b) for b in VsW.basis()] - - images = [to_VsW(pow(x, q) - x) for x in l] - K = VsW.hom(images, VsW).kernel() - - if K.dimension() == 0: - return [] - if K.dimension() == 1: # h is prime - return [(liftb(h),VsW.dimension())] # relative degree - - # choose a such that a^q - a is 0 but a is not in Fp - for a in K.basis(): - # IMPORTANT: This criterion is based on the assumption - # that O.basis() starts with 1. - if a.support() != [0]: - break - else: - raise AssertionError("no appropriate value found") - - a = lift_to_V(a) - # compute the minimal polynomial of a - m = [to_VsW(Ob[0])] # 1 in VsW - apow = a - while True: - v = to_VsW(apow) - try: - sol = matrix(m).solve_left(v) - except ValueError: - m.append(v) - apow = mul_vec(apow, a) - continue - break - - minpol = X**len(sol) - P(list(sol)) - - # The minimal polynomial of a has only linear factors and at least two - # of them. We set f to the first factor and g to the product of the rest. - fac = minpol.factor() - f = fac[0][0] - g = (fac/f).expand() - d,u,v = f.xgcd(g) - - assert d == 1, "Not relatively prime {} and {}".format(f,g) - - # finally, idempotent! - e = lift_to_V(sum([c1*c2 for c1,c2 in zip(u*f,m)])) - - h1 = add(h, matrix([mul_vec(e,Ob[i]) for i in range(n)])) - h2 = add(h, matrix([mul_vec(Ob[0]-e,Ob[i]) for i in range(n)])) - - return split(h1) + split(h2) - - decomposition = [] - for i in range(len(Hb)): - index = i + 1 # Hb starts with H_1 - for prime, degree in split(Hb[i]): - # Compute an element beta in O but not in pO. How to find beta - # is explained in Section 4.8.3 of [Coh1993]. We keep beta - # as a vector over k[x] with respect to the basis of O. - m =[] - for i in range(n): - r = [] - for g in prime._hnf: - r += sum(to(g[j]) * mtable[i][j] for j in range(n)) - m.append(r) - beta = [fr(e) for e in matrix(m).left_kernel().basis()[0]] - - prime.is_prime.set_cache(True) - prime._prime_below = ideal - prime._relative_degree = degree - prime._ramification_index = index - prime._beta = beta - - decomposition.append((prime, degree, index)) - - return decomposition - - -class FunctionFieldMaximalOrderInfinite(FunctionFieldMaximalOrder, FunctionFieldOrderInfinite): - """ - Base class of maximal infinite orders of function fields. - """ - def _repr_(self): - """ - EXAMPLES:: - - sage: FunctionField(QQ,'y').maximal_order_infinite() - Maximal infinite order of Rational function field in y over Rational Field - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return "Maximal infinite order of %s"%(self.function_field(),) - - -class FunctionFieldMaximalOrderInfinite_rational(FunctionFieldMaximalOrderInfinite): - """ - Maximal infinite orders of rational function fields. - - INPUT: - - - ``field`` -- a rational function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari - Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order_infinite(); R # optional - sage.libs.pari - Maximal infinite order of Rational function field in t over Finite Field of size 19 - """ - def __init__(self, field, category=None): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order_infinite() # optional - sage.libs.pari - sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') # optional - sage.libs.pari - """ - FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_rational, - category=PrincipalIdealDomains().or_subcategory(category)) - self._populate_coercion_lists_(coerce_list=[field.constant_base_field()]) - - def _element_constructor_(self, f): - """ - Make ``f`` an element of this order. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: O._element_constructor_(y) - y - sage: O._element_constructor_(1/y) - Traceback (most recent call last): - ... - TypeError: 1/y is not an element of Maximal order of Rational function field in y over Rational Field - """ - F = self.function_field() - try: - f = F(f) - except TypeError: - raise TypeError("unable to convert to an element of {}".format(F)) - - if f.denominator().degree() < f.numerator().degree(): - raise TypeError("{} is not an element of {}".format(f, self)) - - return f - - def basis(self): - """ - Return the basis (=1) of the order as a module over the polynomial ring. - - EXAMPLES:: - - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari - (1,) - """ - return 1/self.function_field().gen() - - def gen(self, n=0): - """ - Return the ``n``-th generator of self. Since there is only one generator ``n`` must be 0. - - EXAMPLES:: - - sage: O = FunctionField(QQ,'y').maximal_order() - sage: O.gen() - y - sage: O.gen(1) - Traceback (most recent call last): - ... - IndexError: there is only one generator - """ - if n != 0: - raise IndexError("there is only one generator") - return self._gen - - def ngens(self): - """ - Return 1 the number of generators of the order. - - EXAMPLES:: - - sage: FunctionField(QQ,'y').maximal_order().ngens() - 1 - """ - return 1 - - def prime_ideal(self): - """ - Return the unique prime ideal of the order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order_infinite() # optional - sage.libs.pari - sage: O.prime_ideal() # optional - sage.libs.pari - Ideal (1/t) of Maximal infinite order of Rational function field in t - over Finite Field of size 19 - """ - return self.ideal( 1/self.function_field().gen() ) - - def ideal(self, *gens): - """ - Return the fractional ideal generated by ``gens``. - - INPUT: - - - ``gens`` -- elements of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order_infinite() - sage: O.ideal(x) - Ideal (x) of Maximal infinite order of Rational function field in x over Rational Field - sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list - True - sage: O.ideal(x^3+1,x^3+6) - Ideal (x^3) of Maximal infinite order of Rational function field in x over Rational Field - sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I - Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field - sage: O.ideal(I) - Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field - """ - if len(gens) == 1: - gens = gens[0] - if not isinstance(gens, (list, tuple)): - if isinstance(gens, FunctionFieldIdeal): - gens = gens.gens() - else: - gens = (gens,) - K = self.function_field() - gens = [K(g) for g in gens] - try: - d = max(g.numerator().degree() - g.denominator().degree() for g in gens if g != 0) - gen = K.gen() ** d - except ValueError: # all gens are zero - gen = K(0) - - return self.ideal_monoid().element_class(self, gen) - - -class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinite): - """ - Maximal infinite orders of function fields. - - INPUT: - - - ``field`` -- function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - def __init__(self, field, category=None): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: TestSuite(O).run() # optional - sage.libs.pari sage.modules - """ - FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) - - M, from_M, to_M = field._inversion_isomorphism() - basis = [from_M(g) for g in M.maximal_order().basis()] - - V, from_V, to_V = field.vector_space() - R = field.base_field().maximal_order_infinite() - - self._basis = tuple(basis) - self._module = V.span_of_basis([to_V(v) for v in basis]) - self._module_base_ring = R - self._to_module = to_V - - def _element_constructor_(self, f): - """ - Make ``f`` an element of this order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.basis() # optional - sage.libs.pari sage.modules - (1, 1/x*y) - sage: 1 in Oinf # optional - sage.libs.pari sage.modules - True - sage: 1/x*y in Oinf # optional - sage.libs.pari sage.modules - True - sage: x*y in Oinf # optional - sage.libs.pari sage.modules - False - sage: 1/x in Oinf # optional - sage.libs.pari sage.modules - True - """ - F = self.function_field() - - try: - f = F(f) - except TypeError: - raise TypeError("unable to convert to an element of {}".format(F)) - - O = F.base_field().maximal_order_infinite() - coordinates = self.coordinate_vector(f) - if not all(c in O for c in coordinates): - raise TypeError("%r is not an element of %r"%(f,self)) - - return f - - def basis(self): - """ - Return a basis of this order as a module over the maximal order - of the base function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.basis() # optional - sage.libs.pari sage.modules - (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) - - :: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.basis() # optional - sage.libs.pari sage.modules - (1, 1/x*y) - """ - return self._basis - - def gen(self, n=0): - """ - Return the ``n``-th generator of the order. - - The basis elements of the order are generators. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.gen() # optional - sage.libs.pari sage.modules - 1 - sage: Oinf.gen(1) # optional - sage.libs.pari sage.modules - 1/x^2*y - sage: Oinf.gen(2) # optional - sage.libs.pari sage.modules - (1/(x^4 + x^3 + x^2))*y^2 - sage: Oinf.gen(3) # optional - sage.libs.pari sage.modules - Traceback (most recent call last): - ... - IndexError: there are only 3 generators - """ - if not ( n >= 0 and n < self.ngens() ): - raise IndexError("there are only {} generators".format(self.ngens())) - - return self._basis[n] - - def ngens(self): - """ - Return the number of generators of the order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.ngens() # optional - sage.libs.pari sage.modules - 3 - """ - return len(self._basis) - - def ideal(self, *gens): - """ - Return the ideal generated by ``gens``. - - INPUT: - - - ``gens`` -- tuple of elements of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari sage.modules - Ideal (y) of Maximal infinite order of Function field - in y defined by y^3 + x^6 + x^4 + x^2 - - :: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: I = Oinf.ideal(x,y); I # optional - sage.libs.pari sage.modules - Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - if len(gens) == 1: - gens = gens[0] - if not type(gens) in (list,tuple): - gens = (gens,) - mgens = [g * b for g in gens for b in self._basis] - return self.ideal_with_gens_over_base(mgens) - - def ideal_with_gens_over_base(self, gens): - """ - Return the ideal generated by ``gens`` as a module. - - INPUT: - - - ``gens`` -- tuple of elements of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) # optional - sage.libs.pari sage.modules - Ideal (y) of Maximal infinite order of Function field in y - defined by y^3 + x^6 + x^4 + x^2 - """ - F = self.function_field() - iF, from_iF, to_iF = F._inversion_isomorphism() - iO = iF.maximal_order() - - ideal = iO.ideal_with_gens_over_base([to_iF(g) for g in gens]) - - if not ideal.is_zero(): - # Now the ideal does not correspond exactly to the ideal in the - # maximal infinite order through the inversion isomorphism. The - # reason is that the ideal also has factors not lying over x. - # The following procedure removes the spurious factors. The idea - # is that for an integral ideal I, J_n = I + (xO)^n stabilizes - # if n is large enough, and then J_n is the I with the spurious - # factors removed. For a fractional ideal, we also need to find - # the largest factor x^m that divides the denominator. - from sage.matrix.special import block_matrix - from .hermite_form_polynomial import reversed_hermite_form - - d = ideal.denominator() - h = ideal.hnf() - x = d.parent().gen() - - # find the largest factor x^m that divides the denominator - i = 0 - while d[i].is_zero(): - i += 1 - d = x ** i - - # find the largest n such that I + (xO)^n stabilizes - h1 = h - MS = h1.matrix_space() - k = MS.identity_matrix() - while True: - k = x * k - - h2 = block_matrix([[h],[k]]) - reversed_hermite_form(h2) - i = 0 - while i < h2.nrows() and h2.row(i).is_zero(): - i += 1 - h2 = h2[i:] # remove zero rows - - if h2 == h1: - break - h1 = h2 - - # reconstruct ideal - ideal = iO._ideal_from_vectors_and_denominator(list(h1), d) - - return self.ideal_monoid().element_class(self, ideal) - - def _to_iF(self, I): - """ - Return the ideal in the inverted function field from ``I``. - - INPUT: - - - ``I`` -- ideal of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.modules - sage: Oinf._to_iF(I) # optional - sage.libs.pari sage.modules - Ideal (1, 1/x*s) of Maximal order of Function field in s - defined by s^2 + x*s + x^3 + x - """ - F = self.function_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - iO = iF.maximal_order() - iI = iO.ideal_with_gens_over_base([to_iF(b) for b in I.gens_over_base()]) - return iI - - def decomposition(self): - r""" - Return prime ideal decomposition of `pO_\infty` where `p` is the unique - prime ideal of the maximal infinite order of the rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.decomposition() # optional - sage.libs.pari sage.modules - [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), - (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - - :: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.decomposition() # optional - sage.libs.pari sage.modules - [(Ideal (1/x*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x, 1, 2)] - - :: - - sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.singular sage.modules - sage: Oinf.decomposition() # optional - sage.libs.singular sage.modules - [(Ideal (1/x^2*y - 1) of Maximal infinite order - of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 1, 1), - (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order - of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 2, 1)] - - :: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.singular sage.modules - sage: Oinf.decomposition() # optional - sage.libs.singular sage.modules - [(Ideal (1/x*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x, 1, 2)] - """ - F = self.function_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - - x = iF.base_field().gen() - iO = iF.maximal_order() - io = iF.base_field().maximal_order() - ip = io.ideal(x) - - dec = [] - for iprime, deg, exp in iO.decomposition(ip): - prime = self.ideal_monoid().element_class(self, iprime) - dec.append((prime, deg, exp)) - return dec - - def different(self): - """ - Return the different ideal of the maximal infinite order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf.different() # optional - sage.libs.pari sage.modules - Ideal (1/x) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - """ - T = self._codifferent_matrix() - codiff_gens = [] - for c in T.inverse().columns(): - codiff_gens.append(sum([ci*bi for ci,bi in zip(c,self.basis())])) - codiff = self.ideal_with_gens_over_base(codiff_gens) - return ~codiff - - @cached_method - def _codifferent_matrix(self): - """ - Return the codifferent matrix of the maximal infinite order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: Oinf._codifferent_matrix() # optional - sage.libs.pari sage.modules - [ 0 1/x] - [ 1/x 1/x^2] - """ - from sage.matrix.constructor import matrix - - rows = [] - for u in self.basis(): - row = [] - for v in self.basis(): - row.append((u*v).trace()) - rows.append(row) - T = matrix(rows) - return T - - def coordinate_vector(self, e): - """ - Return the coordinates of ``e`` with respect to the basis of the order. - - INPUT: - - - ``e`` -- element of the function field - - The returned coordinates are in the base maximal infinite order if and only - if the element is in the order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.modules - sage: f = 1/y^2 # optional - sage.libs.pari sage.modules - sage: f in Oinf # optional - sage.libs.pari sage.modules - True - sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari sage.modules - ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) - """ - return self._module.coordinate_vector(self._to_module(e)) diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py new file mode 100644 index 00000000000..e686228ae85 --- /dev/null +++ b/src/sage/rings/function_field/order_basis.py @@ -0,0 +1,555 @@ +# sage.doctest: optional - sage.modules (because __init__ constructs a vector space) +# some tests are marked # optional - sage.libs.pari (because they use finite fields) +r""" +Orders of function fields given by a basis over the maximal order of the base field +""" + + +from .ideal import FunctionFieldIdeal, FunctionFieldIdeal_module, FunctionFieldIdealInfinite_module +from .order import FunctionFieldOrder, FunctionFieldOrderInfinite + + +class FunctionFieldOrder_basis(FunctionFieldOrder): + """ + Order given by a basis over the maximal order of the base field. + + INPUT: + + - ``basis`` -- list of elements of the function field + + - ``check`` -- (default: ``True``) if ``True``, check whether the module + that ``basis`` generates forms an order + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari + Order in Function field in y defined by y^4 + x*y + 4*x + 1 + + The basis only defines an order if the module it generates is closed under + multiplication and contains the identity element:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: y.is_integral() # optional - sage.libs.singular + False + sage: L.order(y) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: the module generated by basis (1, y, y^2, y^3, y^4) must be closed under multiplication + + The basis also has to be linearly independent and of the same rank as the + degree of the function field of its elements (only checked when ``check`` + is ``True``):: + + sage: L.order(L(x)) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: basis (1, x, x^2, x^3, x^4) is not linearly independent + sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: basis (y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x) is not linearly independent + """ + def __init__(self, basis, check=True): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari + """ + if len(basis) == 0: + raise ValueError("basis must have positive length") + + field = basis[0].parent() + if len(basis) != field.degree(): + raise ValueError("length of basis must equal degree of field") + + FunctionFieldOrder.__init__(self, field, ideal_class=FunctionFieldIdeal_module) + + V, from_V, to_V = field.vector_space() + + R = V.base_field().maximal_order() + self._module = V.span([to_V(b) for b in basis], base_ring=R) + + self._from_module= from_V + self._to_module = to_V + self._basis = tuple(basis) + self._ring = field.polynomial_ring() + self._populate_coercion_lists_(coerce_list=[self._ring]) + + if check: + if self._module.rank() != field.degree(): + raise ValueError("basis {} is not linearly independent".format(basis)) + if not to_V(field(1)) in self._module: + raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) + if not all(to_V(a*b) in self._module for a in basis for b in basis): + raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) + + def _element_constructor_(self, f): + """ + Construct an element of this order from ``f``. + + INPUT: + + - ``f`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.maximal_order()._element_constructor_(x) + x + """ + F = self.function_field() + + try: + f = F(f) + except TypeError: + raise TypeError("unable to convert to an element of {}".format(F)) + + V, fr_V, to_V = F.vector_space() + f_vector = to_V(f) + if f_vector not in self._module: + raise TypeError("{} is not an element of {}".format(f_vector, self)) + + return f + + def ideal_with_gens_over_base(self, gens): + """ + Return the fractional ideal with basis ``gens`` over the + maximal order of the base field. + + It is not checked that the ``gens`` really generates an ideal. + + INPUT: + + - ``gens`` -- list of elements of the function field + + EXAMPLES: + + We construct an ideal in a rational function field:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal([y]); I + Ideal (y) of Maximal order of Rational function field in y over Rational Field + sage: I * I + Ideal (y^2) of Maximal order of Rational function field in y over Rational Field + + We construct some ideals in a nontrivial function field:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari + Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I.module() # optional - sage.libs.pari + Free module of degree 2 and rank 2 over + Maximal order of Rational function field in x over Finite Field of size 7 + Echelon basis matrix: + [1 0] + [0 1] + + There is no check if the resulting object is really an ideal:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari + Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: y in I # optional - sage.libs.pari + True + sage: y^2 in I # optional - sage.libs.pari + False + """ + F = self.function_field() + S = F.base_field().maximal_order() + + gens = [F(a) for a in gens] + + V, from_V, to_V = F.vector_space() + M = V.span([to_V(b) for b in gens], base_ring=S) + + return self.ideal_monoid().element_class(self, M) + + def ideal(self, *gens): + """ + Return the fractional ideal generated by the elements in ``gens``. + + INPUT: + + - ``gens`` -- list of generators or an ideal in a ring which + coerces to this order + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O.ideal(y) + Ideal (y) of Maximal order of Rational function field in y over Rational Field + sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list + True + + A fractional ideal of a nontrivial extension:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: S = L.equation_order() # optional - sage.libs.pari + sage: S.ideal(1/y) # optional - sage.libs.pari + Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari + Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I2 == S.ideal(I) # optional - sage.libs.pari + True + """ + if len(gens) == 1: + gens = gens[0] + if not isinstance(gens, (list, tuple)): + if isinstance(gens, FunctionFieldIdeal): + gens = gens.gens() + else: + gens = [gens] + K = self.function_field() + + return self.ideal_with_gens_over_base([b*K(g) for b in self.basis() for g in gens]) + + def polynomial(self): + """ + Return the defining polynomial of the function field of which this is an order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.polynomial() # optional - sage.libs.pari + y^4 + x*y + 4*x + 1 + """ + return self._field.polynomial() + + def basis(self): + """ + Return a basis of the order over the maximal order of the base field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari + (1, y, y^2, y^3) + """ + return self._basis + + def free_module(self): + """ + Return the free module formed by the basis over the maximal order + of the base function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.free_module() # optional - sage.libs.pari + Free module of degree 4 and rank 4 over Maximal order of Rational + function field in x over Finite Field of size 7 + Echelon basis matrix: + [1 0 0 0] + [0 1 0 0] + [0 0 1 0] + [0 0 0 1] + """ + return self._module + + def coordinate_vector(self, e): + """ + Return the coordinates of ``e`` with respect to the basis of the order. + + INPUT: + + - ``e`` -- element of the order or the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: f = (x + y)^3 # optional - sage.libs.pari + sage: O.coordinate_vector(f) # optional - sage.libs.pari + (x^3, 3*x^2, 3*x, 1) + """ + return self._module.coordinate_vector(self._to_module(e), check=False) + + +class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): + """ + Order given by a basis over the infinite maximal order of the base field. + + INPUT: + + - ``basis`` -- elements of the function field + + - ``check`` -- boolean (default: ``True``); if ``True``, check the basis generates + an order + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari + Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 + + The basis only defines an order if the module it generates is closed under + multiplication and contains the identity element (only checked when + ``check`` is ``True``):: + + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari + Traceback (most recent call last): + ... + ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication + + The basis also has to be linearly independent and of the same rank as the + degree of the function field of its elements (only checked when ``check`` + is ``True``):: + + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari + Traceback (most recent call last): + ... + ValueError: The given basis vectors must be linearly independent. + + Note that 1 does not need to be an element of the basis, as long as it is + in the module spanned by it:: + + sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari + Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 + sage: O.basis() # optional - sage.libs.pari + (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) + """ + def __init__(self, basis, check=True): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order_infinite() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari + """ + if len(basis) == 0: + raise ValueError("basis must have positive length") + + field = basis[0].parent() + if len(basis) != field.degree(): + raise ValueError("length of basis must equal degree of field") + + FunctionFieldOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_module) + + # function field element f is in this order if and only if + # W.coordinate_vector(to(f)) in M + V, fr, to = field.vector_space() + R = field.base_field().maximal_order_infinite() + W = V.span_of_basis([to(v) for v in basis]) + from sage.modules.free_module import FreeModule + M = FreeModule(R, W.dimension()) + self._basis = tuple(basis) + self._ambient_space = W + self._module = M + + self._ring = field.polynomial_ring() + self._populate_coercion_lists_(coerce_list=[self._ring]) + + if check: + if self._module.rank() != field.degree(): + raise ValueError("basis {} is not linearly independent".format(basis)) + if not W.coordinate_vector(to(field(1))) in self._module: + raise ValueError("the identity element must be in the module spanned by basis {}".format(basis)) + if not all(W.coordinate_vector(to(a*b)) in self._module for a in basis for b in basis): + raise ValueError("the module generated by basis {} must be closed under multiplication".format(basis)) + + def _element_constructor_(self, f): + """ + Construct an element of this order. + + INPUT: + + - ``f`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O(x) + x + sage: O(1/x) + Traceback (most recent call last): + ... + TypeError: 1/x is not an element of Maximal order of Rational function field in x over Rational Field + """ + F = self.function_field() + try: + f = F(f) + except TypeError: + raise TypeError("unable to convert to an element of {}".format(F)) + + V, fr_V, to_V = F.vector_space() + W = self._ambient_space + if not W.coordinate_vector(to_V(f)) in self._module: + raise TypeError("{} is not an element of {}".format(f, self)) + + return f + + def ideal_with_gens_over_base(self, gens): + """ + Return the fractional ideal with basis ``gens`` over the + maximal order of the base field. + + It is not checked that ``gens`` really generates an ideal. + + INPUT: + + - ``gens`` -- list of elements that are a basis for the ideal over the + maximal order of the base field + + EXAMPLES: + + We construct an ideal in a rational function field:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal([y]); I + Ideal (y) of Maximal order of Rational function field in y over Rational Field + sage: I*I + Ideal (y^2) of Maximal order of Rational function field in y over Rational Field + + We construct some ideals in a nontrivial function field:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order(); O # optional - sage.libs.pari + Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: I.module() # optional - sage.libs.pari + Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 + Echelon basis matrix: + [1 0] + [0 1] + + There is no check if the resulting object is really an ideal:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari + Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: y in I # optional - sage.libs.pari + True + sage: y^2 in I # optional - sage.libs.pari + False + """ + F = self.function_field() + S = F.base_field().maximal_order_infinite() + + gens = [F(a) for a in gens] + + V, from_V, to_V = F.vector_space() + M = V.span([to_V(b) for b in gens], base_ring=S) # not work + + return self.ideal_monoid().element_class(self, M) + + def ideal(self, *gens): + """ + Return the fractional ideal generated by the elements in ``gens``. + + INPUT: + + - ``gens`` -- list of generators or an ideal in a ring which coerces + to this order + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O.ideal(y) + Ideal (y) of Maximal order of Rational function field in y over Rational Field + sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list + True + + A fractional ideal of a nontrivial extension:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: O = K.maximal_order_infinite() + sage: I = O.ideal(x^2-4) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) # optional - sage.libs.singular + """ + if len(gens) == 1: + gens = gens[0] + if not isinstance(gens, (list, tuple)): + if isinstance(gens, FunctionFieldIdeal): + gens = gens.gens() + else: + gens = [gens] + K = self.function_field() + + return self.ideal_with_gens_over_base([b*K(g) for b in self.basis() for g in gens]) + + def polynomial(self): + """ + Return the defining polynomial of the function field of which this is an order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.polynomial() # optional - sage.libs.pari + y^4 + x*y + 4*x + 1 + """ + return self._field.polynomial() + + def basis(self): + """ + Return a basis of this order over the maximal order of the base field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari + (1, y, y^2, y^3) + """ + return self._basis + + def free_module(self): + """ + Return the free module formed by the basis over the maximal order of + the base field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.free_module() # optional - sage.libs.pari + Free module of degree 4 and rank 4 over Maximal order of Rational + function field in x over Finite Field of size 7 + Echelon basis matrix: + [1 0 0 0] + [0 1 0 0] + [0 0 1 0] + [0 0 0 1] + """ + return self._module diff --git a/src/sage/rings/function_field/order_global.py b/src/sage/rings/function_field/order_global.py new file mode 100644 index 00000000000..0c6b04ade88 --- /dev/null +++ b/src/sage/rings/function_field/order_global.py @@ -0,0 +1,363 @@ +# sage.doctest: optional - sage.modules (because __init__ constructs a vector space) +# some tests are marked # optional - sage.libs.pari (because they use finite fields) +r""" +Maximal orders of global function fields +""" + +from sage.misc.cachefunc import cached_method + +from .ideal import FunctionFieldIdeal_global +from .order_polymod import FunctionFieldMaximalOrder_polymod + + +class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): + """ + Maximal orders of global function fields. + + INPUT: + + - ``field`` -- function field to which this maximal order belongs + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: L.maximal_order() + Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 + """ + + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: TestSuite(O).run() + """ + FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) + + @cached_method + def p_radical(self, prime): + """ + Return the ``prime``-radical of the maximal order. + + INPUT: + + - ``prime`` -- prime ideal of the maximal order of the base + rational function field + + The algorithm is outlined in Section 6.1.3 of [Coh1993]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) + sage: o = K.maximal_order() + sage: O = F.maximal_order() + sage: p = o.ideal(x + 1) + sage: O.p_radical(p) + Ideal (x + 1) of Maximal order of Function field in y + defined by y^3 + x^6 + x^4 + x^2 + """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + g = prime.gens()[0] + + if not (g.denominator() == 1 and g.numerator().is_irreducible()): + raise ValueError('not a prime ideal') + + F = self.function_field() + n = F.degree() + o = prime.ring() + p = g.numerator() + + # Fp is isomorphic to the residue field o/p + Fp, fr_Fp, to_Fp = o._residue_field_global(p) + + # exp = q^j should be at least extension degree where q is + # the order of the residue field o/p + q = F.constant_base_field().order()**p.degree() + exp = q + while exp <= F.degree(): + exp = exp**q + + # radical equals to the kernel of the map x |-> x^exp + mat = [] + for g in self.basis(): + v = [to_Fp(c) for c in self._coordinate_vector(g**exp)] + mat.append(v) + mat = matrix(Fp, mat) + ker = mat.kernel() + + # construct module generators of the p-radical + vecs = [] + for i in range(n): + v = vector([p if j == i else 0 for j in range(n)]) + vecs.append(v) + for b in ker.basis(): + v = vector([fr_Fp(c) for c in b]) + vecs.append(v) + + return self._ideal_from_vectors(vecs) + + @cached_method + def decomposition(self, ideal): + """ + Return the decomposition of the prime ideal. + + INPUT: + + - ``ideal`` -- prime ideal of the base maximal order + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: o = K.maximal_order() + sage: O = F.maximal_order() + sage: p = o.ideal(x + 1) + sage: O.decomposition(p) + [(Ideal (x + 1, y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), + (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] + """ + from sage.matrix.constructor import matrix + + F = self.function_field() + n = F.degree() + + p = ideal.gen().numerator() + o = ideal.ring() + + # Fp is isomorphic to the residue field o/p + Fp, fr, to = o._residue_field_global(p) + P,X = Fp['X'].objgen() + + V = Fp**n # Ob = O/pO + + mtable = [] + for i in range(n): + row = [] + for j in range(n): + row.append( V([to(e) for e in self._mtable[i][j]]) ) + mtable.append(row) + + if p not in self._kummer_places: + ##################################### + # Decomposition by Kummer's theorem # + ##################################### + # gen is self._kummer_gen + gen_vec_pow = self._kummer_gen_vec_pow + mul_vecs = self._mul_vecs + + f = self._kummer_polynomial + fp = P([to(c.numerator()) for c in f.list()]) + decomposition = [] + for q, exp in fp.factor(): + # construct O.ideal([p,q(gen)]) + gen_vecs = list(matrix.diagonal(n * [p])) + c = q.list() + + # q(gen) in vector form + qgen = sum(fr(c[i]) * gen_vec_pow[i] for i in range(len(c))) + + I = matrix.identity(o._ring, n) + for i in range(n): + gen_vecs.append(mul_vecs(qgen,I[i])) + prime = self._ideal_from_vectors_and_denominator(gen_vecs) + + # Compute an element beta in O but not in pO. How to find beta + # is explained in Section 4.8.3 of [Coh1993]. We keep beta + # as a vector over k[x] with respect to the basis of O. + + # p and qgen generates the prime; modulo pO, qgenb generates the prime + qgenb = [to(qgen[i]) for i in range(n)] + m =[] + for i in range(n): + m.append(sum(qgenb[j] * mtable[i][j] for j in range(n))) + beta = [fr(coeff) for coeff in matrix(m).left_kernel().basis()[0]] + + prime.is_prime.set_cache(True) + prime._prime_below = ideal + prime._relative_degree = q.degree() + prime._ramification_index = exp + prime._beta = beta + + prime._kummer_form = (p, qgen) + + decomposition.append((prime, q.degree(), exp)) + else: + ############################# + # Buchman-Lenstra algorithm # + ############################# + from sage.matrix.special import block_matrix + from sage.modules.free_module_element import vector + + pO = self.ideal(p) + Ip = self.p_radical(ideal) + Ob = matrix.identity(Fp, n) + + def bar(I): # transfer to O/pO + m = [] + for v in I._hnf: + m.append([to(e) for e in v]) + h = matrix(m).echelon_form() + return cut_last_zero_rows(h) + + def liftb(Ib): + m = [vector([fr(e) for e in v]) for v in Ib] + m += [v for v in pO._hnf] + return self._ideal_from_vectors_and_denominator(m,1) + + def cut_last_zero_rows(h): + i = h.nrows() + while i > 0 and h.row(i-1).is_zero(): + i -= 1 + return h[:i] + + def mul_vec(v1,v2): + s = 0 + for i in range(n): + for j in range(n): + s += v1[i] * v2[j] * mtable[i][j] + return s + + def pow(v, r): # r > 0 + m = v + while r > 1: + m = mul_vec(m,v) + r -= 1 + return m + + # Algorithm 6.2.7 of [Coh1993] + def div(Ib, Jb): + # compute a basis of Jb/Ib + sJb = Jb.row_space() + sIb = Ib.row_space() + sJbsIb,proj_sJbsIb,lift_sJbsIb = sJb.quotient_abstract(sIb) + supplement_basis = [lift_sJbsIb(v) for v in sJbsIb.basis()] + + m = [] + for b in V.gens(): # basis of Ob = O/pO + b_row = [] # row vector representation of the map a -> a*b + for a in supplement_basis: + b_row += lift_sJbsIb(proj_sJbsIb( mul_vec(a,b) )) + m.append(b_row) + return matrix(Fp,n,m).left_kernel().basis_matrix() + + # Algorithm 6.2.5 of [Coh1993] + def mul(Ib, Jb): + m = [] + for v1 in Ib: + for v2 in Jb: + m.append(mul_vec(v1,v2)) + h = matrix(m).echelon_form() + return cut_last_zero_rows(h) + + def add(Ib,Jb): + m = block_matrix([[Ib], [Jb]]) + h = m.echelon_form() + return cut_last_zero_rows(h) + + # K_1, K_2, ... + Lb = IpOb = bar(Ip+pO) + Kb = [Lb] + while not Lb.is_zero(): + Lb = mul(Lb,IpOb) + Kb.append(Lb) + + # J_1, J_2, ... + Jb =[Kb[0]] + [div(Kb[j],Kb[j-1]) for j in range(1,len(Kb))] + + # H_1, H_2, ... + Hb = [div(Jb[j],Jb[j+1]) for j in range(len(Jb)-1)] + [Jb[-1]] + + q = Fp.order() + + def split(h): + # VsW represents O/H as a vector space + W = h.row_space() # H/pO + VsW,to_VsW,lift_to_V = V.quotient_abstract(W) + + # compute the space K of elements in O/H that satisfy a^q-a=0 + l = [lift_to_V(b) for b in VsW.basis()] + + images = [to_VsW(pow(x, q) - x) for x in l] + K = VsW.hom(images, VsW).kernel() + + if K.dimension() == 0: + return [] + if K.dimension() == 1: # h is prime + return [(liftb(h),VsW.dimension())] # relative degree + + # choose a such that a^q - a is 0 but a is not in Fp + for a in K.basis(): + # IMPORTANT: This criterion is based on the assumption + # that O.basis() starts with 1. + if a.support() != [0]: + break + else: + raise AssertionError("no appropriate value found") + + a = lift_to_V(a) + # compute the minimal polynomial of a + m = [to_VsW(Ob[0])] # 1 in VsW + apow = a + while True: + v = to_VsW(apow) + try: + sol = matrix(m).solve_left(v) + except ValueError: + m.append(v) + apow = mul_vec(apow, a) + continue + break + + minpol = X**len(sol) - P(list(sol)) + + # The minimal polynomial of a has only linear factors and at least two + # of them. We set f to the first factor and g to the product of the rest. + fac = minpol.factor() + f = fac[0][0] + g = (fac/f).expand() + d,u,v = f.xgcd(g) + + assert d == 1, "Not relatively prime {} and {}".format(f,g) + + # finally, idempotent! + e = lift_to_V(sum([c1*c2 for c1,c2 in zip(u*f,m)])) + + h1 = add(h, matrix([mul_vec(e,Ob[i]) for i in range(n)])) + h2 = add(h, matrix([mul_vec(Ob[0]-e,Ob[i]) for i in range(n)])) + + return split(h1) + split(h2) + + decomposition = [] + for i in range(len(Hb)): + index = i + 1 # Hb starts with H_1 + for prime, degree in split(Hb[i]): + # Compute an element beta in O but not in pO. How to find beta + # is explained in Section 4.8.3 of [Coh1993]. We keep beta + # as a vector over k[x] with respect to the basis of O. + m =[] + for i in range(n): + r = [] + for g in prime._hnf: + r += sum(to(g[j]) * mtable[i][j] for j in range(n)) + m.append(r) + beta = [fr(e) for e in matrix(m).left_kernel().basis()[0]] + + prime.is_prime.set_cache(True) + prime._prime_below = ideal + prime._relative_degree = degree + prime._ramification_index = index + prime._beta = beta + + decomposition.append((prime, degree, index)) + + return decomposition diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py new file mode 100644 index 00000000000..8e458b3458b --- /dev/null +++ b/src/sage/rings/function_field/order_polymod.py @@ -0,0 +1,1072 @@ +# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) +# sage.doctest: optional - sage.modules (because __init__ constructs a vector space) +r""" +Orders of function fields - polymod implementation +""" + +from sage.arith.functions import lcm +from sage.misc.cachefunc import cached_method +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + +from .ideal import ( + FunctionFieldIdeal, + FunctionFieldIdeal_polymod, + FunctionFieldIdealInfinite_polymod +) +from .order import FunctionFieldMaximalOrder, FunctionFieldMaximalOrderInfinite + + +class FunctionFieldMaximalOrder_polymod(FunctionFieldMaximalOrder): + """ + Maximal orders of extensions of function fields. + """ + + def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: TestSuite(O).run() + """ + FunctionFieldMaximalOrder.__init__(self, field, ideal_class) + + from sage.modules.free_module_element import vector + from .function_field import FunctionField_integral + + if isinstance(field, FunctionField_integral): + basis = field._maximal_order_basis() + else: + model, from_model, to_model = field.monic_integral_model('z') + basis = [from_model(g) for g in model._maximal_order_basis()] + + V, fr, to = field.vector_space() + R = field.base_field().maximal_order() + + # This module is over R, but linear algebra over R (MaximalOrder) + # is not well supported in Sage. So we keep it as a vector space + # over rational function field. + self._module = V.span_of_basis([to(b) for b in basis]) + self._module_base_ring = R + self._basis = tuple(basis) + self._from_module = fr + self._to_module = to + + # multiplication table (lower triangular) + n = len(basis) + self._mtable = [] + for i in range(n): + row = [] + for j in range(n): + row.append(self._coordinate_vector(basis[i] * basis[j])) + self._mtable.append(row) + + zero = vector(R._ring, n * [0]) + + def mul_vecs(f, g): + s = zero + for i in range(n): + if f[i].is_zero(): + continue + for j in range(n): + if g[j].is_zero(): + continue + s += f[i] * g[j] * self._mtable[i][j] + return s + self._mul_vecs = mul_vecs + + # We prepare for using Kummer's theorem to decompose primes. Note + # that Kummer's theorem applies to most places. Here we find + # places for which the theorem does not apply. + + # this element is integral over k[x] and a generator of the field. + for gen in basis: + phi = gen.minimal_polynomial() + if phi.degree() == n: + break + + assert phi.degree() == n + + gen_vec = self._coordinate_vector(gen) + g = gen_vec.parent().gen(0) # x + gen_vec_pow = [g] + for i in range(n): + g = mul_vecs(g, gen_vec) + gen_vec_pow.append(g) + + # find places where {1,gen,...,gen^(n-1)} is not integral basis + W = V.span_of_basis([to(gen ** i) for i in range(phi.degree())]) + + supp = [] + for g in basis: + for c in W.coordinate_vector(to(g), check=False): + if not c.is_zero(): + supp += [f for f,_ in c.denominator().factor()] + supp = set(supp) + + self._kummer_gen = gen + self._kummer_gen_vec_pow = gen_vec_pow + self._kummer_polynomial = phi + self._kummer_places = supp + + def _element_constructor_(self, f): + """ + Construct an element of this order from ``f``. + + INPUT: + + - ``f`` -- element convertible to the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] + sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) + sage: O = L.maximal_order() + sage: y in O + True + sage: 1/y in O + False + sage: x in O + True + sage: 1/x in O + False + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: O = L.maximal_order() + sage: 1 in O + True + sage: y in O + False + sage: x*y in O + True + sage: x^2*y in O + True + """ + F = self.function_field() + f = F(f) + # check if f is in this order + if not all(e in self._module_base_ring for e in self.coordinate_vector(f)): + raise TypeError( "{} is not an element of {}".format(f, self) ) + + return f + + def ideal_with_gens_over_base(self, gens): + """ + Return the fractional ideal with basis ``gens`` over the + maximal order of the base field. + + INPUT: + + - ``gens`` -- list of elements that generates the ideal over the + maximal order of the base field + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.maximal_order(); O + Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + sage: I = O.ideal_with_gens_over_base([1, y]); I + Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + sage: I.module() + Free module of degree 2 and rank 2 over + Maximal order of Rational function field in x over Finite Field of size 7 + Echelon basis matrix: + [1 0] + [0 1] + + There is no check if the resulting object is really an ideal:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.equation_order() + sage: I = O.ideal_with_gens_over_base([y]); I + Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: y in I + True + sage: y^2 in I + False + """ + return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) + + def _ideal_from_vectors(self, vecs): + """ + Return an ideal generated as a module by vectors over rational function + field. + + INPUT: + + - ``vec`` -- list of vectors + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: v1 = O.coordinate_vector(x^3+1) + sage: v2 = O.coordinate_vector(y) + sage: v1 + (x^3 + 1, 0) + sage: v2 + (0, 1) + sage: O._ideal_from_vectors([v1,v2]) + Ideal (y) of Maximal order of Function field in y + defined by y^2 + 6*x^3 + 6 + """ + d = lcm([v.denominator() for v in vecs]) + vecs = [[(d*c).numerator() for c in v] for v in vecs] + return self._ideal_from_vectors_and_denominator(vecs, d, check=False) + + def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): + """ + Return an ideal generated as a module by vectors divided by ``d`` over + the polynomial ring underlying the rational function field. + + INPUT: + + - ``vec`` -- list of vectors over the polynomial ring + + - ``d`` -- (default: 1) a nonzero element of the polynomial ring + + - ``check`` -- boolean (default: ``True``); if ``True``, compute the real + denominator of the vectors, possibly different from ``d``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: I = O.ideal(y^2) + sage: m = I.basis_matrix() + sage: v1 = m[0] + sage: v2 = m[1] + sage: v1 + (x^3 + 1, 0) + sage: v2 + (0, x^3 + 1) + sage: O._ideal_from_vectors([v1,v2]) # indirect doctest + Ideal (x^3 + 1) of Maximal order of Function field in y + defined by y^2 + 6*x^3 + 6 + """ + from sage.matrix.constructor import matrix + from .hermite_form_polynomial import reversed_hermite_form + + R = self._module_base_ring._ring + + d = R(d) # make it sure that d is in the polynomial ring + + if check and not d.is_one(): # check if d is true denominator + M = [] + g = d + for v in vecs: + for c in v: + g = g.gcd(c) + if g.is_one(): + break + else: + M += list(v) + continue # for v in vecs + mat = matrix(R, vecs) + break + else: + d = d // g + mat = matrix(R, len(vecs), [c // g for c in M]) + else: + mat = matrix(R, vecs) + + # IMPORTANT: make it sure that pivot polynomials monic + # so that we get a unique hnf. Here the hermite form + # algorithm also makes the pivots monic. + + # compute the reversed hermite form with zero rows deleted + reversed_hermite_form(mat) + i = 0 + while i < mat.nrows() and mat.row(i).is_zero(): + i += 1 + hnf = mat[i:] # remove zero rows + + return self.ideal_monoid().element_class(self, hnf, d) + + def ideal(self, *gens, **kwargs): + """ + Return the fractional ideal generated by the elements in ``gens``. + + INPUT: + + - ``gens`` -- list of generators + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: O = K.maximal_order() + sage: I = O.ideal(x^2 - 4) + sage: L. = K.extension(y^2 - x^3 - 1) + sage: S = L.maximal_order() + sage: S.ideal(1/y) + Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field + in y defined by y^2 + 6*x^3 + 6 + sage: I2 = S.ideal(x^2 - 4); I2 + Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + sage: I2 == S.ideal(I) + True + + sage: K. = FunctionField(QQ); R. = K[] + sage: O = K.maximal_order() + sage: I = O.ideal(x^2 - 4) + sage: L. = K.extension(y^2 - x^3 - 1) + sage: S = L.maximal_order() + sage: S.ideal(1/y) + Ideal ((1/(x^3 + 1))*y) of + Maximal order of Function field in y defined by y^2 - x^3 - 1 + sage: I2 = S.ideal(x^2-4); I2 + Ideal (x^2 - 4) of Maximal order of Function field in y defined by y^2 - x^3 - 1 + sage: I2 == S.ideal(I) + True + """ + if len(gens) == 1: + gens = gens[0] + if not isinstance(gens, (list, tuple)): + if isinstance(gens, FunctionFieldIdeal): + gens = gens.gens() + else: + gens = (gens,) + F = self.function_field() + mgens = [b*F(g) for g in gens for b in self.basis()] + return self.ideal_with_gens_over_base(mgens) + + def polynomial(self): + """ + Return the defining polynomial of the function field of which this is an order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.equation_order() + sage: O.polynomial() + y^4 + x*y + 4*x + 1 + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.equation_order() + sage: O.polynomial() + y^4 + x*y + 4*x + 1 + """ + return self._field.polynomial() + + def basis(self): + """ + Return a basis of the order over the maximal order of the base function + field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.equation_order() + sage: O.basis() + (1, y, y^2, y^3) + + sage: K. = FunctionField(QQ) + sage: R. = PolynomialRing(K) + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) + sage: O = F.maximal_order() + sage: O.basis() + (1, 1/x^4*y, 1/x^9*y^2, 1/x^13*y^3) + """ + return self._basis + + def gen(self, n=0): + """ + Return the ``n``-th generator of the order. + + The basis elements of the order are generators. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: O = L.maximal_order() + sage: O.gen() + 1 + sage: O.gen(1) + y + sage: O.gen(2) + (1/(x^3 + x^2 + x))*y^2 + sage: O.gen(3) + Traceback (most recent call last): + ... + IndexError: there are only 3 generators + """ + if not ( n >= 0 and n < self.ngens() ): + raise IndexError("there are only {} generators".format(self.ngens())) + + return self._basis[n] + + def ngens(self): + """ + Return the number of generators of the order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = L.maximal_order() + sage: Oinf.ngens() + 3 + """ + return len(self._basis) + + def free_module(self): + """ + Return the free module formed by the basis over the maximal order of the base field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O.free_module() + Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 + User basis matrix: + [1 0 0 0] + [0 1 0 0] + [0 0 1 0] + [0 0 0 1] + """ + return self._module.change_ring(self._module_base_ring) + + def coordinate_vector(self, e): + """ + Return the coordinates of ``e`` with respect to the basis of this order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O.coordinate_vector(y) + (0, 1, 0, 0) + sage: O.coordinate_vector(x*y) + (0, x, 0, 0) + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.equation_order() + sage: f = (x + y)^3 + sage: O.coordinate_vector(f) + (x^3, 3*x^2, 3*x, 1) + """ + return self._module.coordinate_vector(self._to_module(e)) + + def _coordinate_vector(self, e): + """ + Return the coordinate vector of ``e`` with respect to the basis + of the order. + + Assuming ``e`` is in the maximal order, the coordinates are given + as univariate polynomials in the underlying ring of the maximal + order of the rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O._coordinate_vector(y) + (0, 1, 0, 0) + sage: O._coordinate_vector(x*y) + (0, x, 0, 0) + """ + from sage.modules.free_module_element import vector + + v = self._module.coordinate_vector(self._to_module(e), check=False) + return vector([c.numerator() for c in v]) + + @cached_method + def different(self): + """ + Return the different ideal of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O.different() + Ideal (y^3 + 2*x) + of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 + """ + return ~self.codifferent() + + @cached_method + def codifferent(self): + """ + Return the codifferent ideal of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O.codifferent() + Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 + + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 + + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y + + 6*x/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4)) of Maximal order of Function field + in y defined by y^4 + x*y + 4*x + 1 + """ + T = self._codifferent_matrix() + return self._ideal_from_vectors(T.inverse().columns()) + + @cached_method + def _codifferent_matrix(self): + """ + Return the matrix `T` defined in Proposition 4.8.19 of [Coh1993]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: O._codifferent_matrix() + [ 4 0 0 4*x] + [ 0 0 4*x 5*x + 3] + [ 0 4*x 5*x + 3 0] + [ 4*x 5*x + 3 0 3*x^2] + """ + from sage.matrix.constructor import matrix + + rows = [] + for u in self.basis(): + row = [] + for v in self.basis(): + row.append((u*v).trace()) + rows.append(row) + T = matrix(rows) + return T + + @cached_method + def decomposition(self, ideal): + """ + Return the decomposition of the prime ideal. + + INPUT: + + - ``ideal`` -- prime ideal of the base maximal order + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: o = K.maximal_order() + sage: O = F.maximal_order() + sage: p = o.ideal(x + 1) + sage: O.decomposition(p) + [(Ideal (x + 1, y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), + (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] + + ALGORITHM: + + In principle, we're trying to compute a primary decomposition + of the extension of ``ideal`` in ``self`` (an order, and therefore + a ring). However, while we have primary decomposition methods + for polynomial rings, we lack any such method for an order. + Therefore, we construct ``self`` mod ``ideal`` as a + finite-dimensional algebra, a construct for which we do + support primary decomposition. + + See :trac:`28094` and https://github.com/sagemath/sage/files/10659303/decomposition.pdf.gz + + .. TODO:: + + Use Kummer's theorem to shortcut this code if possible, like as + done in :meth:`FunctionFieldMaximalOrder_global.decomposition()` + + """ + from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + F = self.function_field() + n = F.degree() + + # Base rational function field + K = self.function_field().base_field() + + # Univariate polynomial ring isomorphic to the maximal order of K + o = PolynomialRing(K.constant_field(), K.gen()) + + # Prime ideal in o defined by the generator of ideal in the maximal + # order of K + p = o(ideal.gen().numerator()) + + # Residue field k = o mod p + k = o.quo(p) + + # Given an element of the function field expressed as a K-vector times + # the basis of this order, construct the n n-by-n matrices that show + # how to multiply by each of the basis elements. + matrices = [matrix(o, [self.coordinate_vector(b1*b2) for b1 in self.basis()]) + for b2 in self.basis()] + + # Let O denote the maximal order self. When reduced modulo p, + # matrices_reduced give the multiplication matrices used to form the + # algebra O mod pO. + matrices_reduced = list(map(lambda M: M.mod(p), matrices)) + A = FiniteDimensionalAlgebra(k, matrices_reduced) + + # Each prime ideal of the algebra A corresponds to a prime ideal of O, + # and since the algebra is an Artinian ring, all of its prime ideals + # are maximal [stacks 00JA]. Thus, we find all of our factors by + # iterating over the algebra's maximal ideals. + factors = [] + for q in A.maximal_ideals(): + if q == A.zero_ideal(): + # The zero ideal is the unique maximal ideal, which means that + # A is a field, and the ideal itself is a prime ideal. + P = self.ideal(p) + + P.is_prime.set_cache(True) + P._prime_below = ideal + P._relative_degree = n + P._ramification_index = 1 + P._beta = [1] + [0]*(n-1) + else: + Q = q.basis_matrix().apply_map(lambda e: e.lift()) + P = self.ideal(p, *Q*vector(self.basis())) + + # Now we compute an element beta in O but not in pO such that + # beta*P in pO. + + # Since beta is in k[x]-module O, we keep beta as a vector + # in k[x] with respect to the basis of O. As long as at least + # one element in this vector is not divisible by p, beta will + # not be in pO. To ensure that beta*P is in pO, multiplying + # beta by each of P's generators must produce a vector whose + # elements are multiples of p. We can ensure that all this + # occurs by constructing a matrix in k, and finding a non-zero + # vector in the kernel of the matrix. + + m =[] + for g in q.basis_matrix(): + m.extend(matrix([g * mr for mr in matrices_reduced]).columns()) + beta = [c.lift() for c in matrix(m).right_kernel().basis()[0]] + + r = q + index = 1 + while True: + rq = r*q + if rq == r: + break + r = rq + index = index + 1 + + P.is_prime.set_cache(True) + P._prime_below = ideal + P._relative_degree = n - q.basis_matrix().nrows() + P._ramification_index = index + P._beta = beta + + factors.append((P, P._relative_degree, P._ramification_index)) + + return factors + + +class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinite): + """ + Maximal infinite orders of function fields. + + INPUT: + + - ``field`` -- function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: F.maximal_order_infinite() + Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: L.maximal_order_infinite() + Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + def __init__(self, field, category=None): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: O = F.maximal_order_infinite() + sage: TestSuite(O).run() + """ + FunctionFieldMaximalOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) + + M, from_M, to_M = field._inversion_isomorphism() + basis = [from_M(g) for g in M.maximal_order().basis()] + + V, from_V, to_V = field.vector_space() + R = field.base_field().maximal_order_infinite() + + self._basis = tuple(basis) + self._module = V.span_of_basis([to_V(v) for v in basis]) + self._module_base_ring = R + self._to_module = to_V + + def _element_constructor_(self, f): + """ + Make ``f`` an element of this order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.basis() + (1, 1/x*y) + sage: 1 in Oinf + True + sage: 1/x*y in Oinf + True + sage: x*y in Oinf + False + sage: 1/x in Oinf + True + """ + F = self.function_field() + + try: + f = F(f) + except TypeError: + raise TypeError("unable to convert to an element of {}".format(F)) + + O = F.base_field().maximal_order_infinite() + coordinates = self.coordinate_vector(f) + if not all(c in O for c in coordinates): + raise TypeError("%r is not an element of %r"%(f,self)) + + return f + + def basis(self): + """ + Return a basis of this order as a module over the maximal order + of the base function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.basis() + (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) + + :: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.basis() + (1, 1/x*y) + """ + return self._basis + + def gen(self, n=0): + """ + Return the ``n``-th generator of the order. + + The basis elements of the order are generators. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.gen() + 1 + sage: Oinf.gen(1) + 1/x^2*y + sage: Oinf.gen(2) + (1/(x^4 + x^3 + x^2))*y^2 + sage: Oinf.gen(3) + Traceback (most recent call last): + ... + IndexError: there are only 3 generators + """ + if not ( n >= 0 and n < self.ngens() ): + raise IndexError("there are only {} generators".format(self.ngens())) + + return self._basis[n] + + def ngens(self): + """ + Return the number of generators of the order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.ngens() + 3 + """ + return len(self._basis) + + def ideal(self, *gens): + """ + Return the ideal generated by ``gens``. + + INPUT: + + - ``gens`` -- tuple of elements of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = F.maximal_order_infinite() + sage: I = Oinf.ideal(x,y); I + Ideal (y) of Maximal infinite order of Function field + in y defined by y^3 + x^6 + x^4 + x^2 + + :: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: I = Oinf.ideal(x,y); I + Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + if len(gens) == 1: + gens = gens[0] + if not type(gens) in (list,tuple): + gens = (gens,) + mgens = [g * b for g in gens for b in self._basis] + return self.ideal_with_gens_over_base(mgens) + + def ideal_with_gens_over_base(self, gens): + """ + Return the ideal generated by ``gens`` as a module. + + INPUT: + + - ``gens`` -- tuple of elements of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = F.maximal_order_infinite() + sage: Oinf.ideal_with_gens_over_base((x^2, y, (1/(x^2 + x + 1))*y^2)) + Ideal (y) of Maximal infinite order of Function field in y + defined by y^3 + x^6 + x^4 + x^2 + """ + F = self.function_field() + iF, from_iF, to_iF = F._inversion_isomorphism() + iO = iF.maximal_order() + + ideal = iO.ideal_with_gens_over_base([to_iF(g) for g in gens]) + + if not ideal.is_zero(): + # Now the ideal does not correspond exactly to the ideal in the + # maximal infinite order through the inversion isomorphism. The + # reason is that the ideal also has factors not lying over x. + # The following procedure removes the spurious factors. The idea + # is that for an integral ideal I, J_n = I + (xO)^n stabilizes + # if n is large enough, and then J_n is the I with the spurious + # factors removed. For a fractional ideal, we also need to find + # the largest factor x^m that divides the denominator. + from sage.matrix.special import block_matrix + from .hermite_form_polynomial import reversed_hermite_form + + d = ideal.denominator() + h = ideal.hnf() + x = d.parent().gen() + + # find the largest factor x^m that divides the denominator + i = 0 + while d[i].is_zero(): + i += 1 + d = x ** i + + # find the largest n such that I + (xO)^n stabilizes + h1 = h + MS = h1.matrix_space() + k = MS.identity_matrix() + while True: + k = x * k + + h2 = block_matrix([[h],[k]]) + reversed_hermite_form(h2) + i = 0 + while i < h2.nrows() and h2.row(i).is_zero(): + i += 1 + h2 = h2[i:] # remove zero rows + + if h2 == h1: + break + h1 = h2 + + # reconstruct ideal + ideal = iO._ideal_from_vectors_and_denominator(list(h1), d) + + return self.ideal_monoid().element_class(self, ideal) + + def _to_iF(self, I): + """ + Return the ideal in the inverted function field from ``I``. + + INPUT: + + - ``I`` -- ideal of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: I = Oinf.ideal(y) + sage: Oinf._to_iF(I) + Ideal (1, 1/x*s) of Maximal order of Function field in s + defined by s^2 + x*s + x^3 + x + """ + F = self.function_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + iO = iF.maximal_order() + iI = iO.ideal_with_gens_over_base([to_iF(b) for b in I.gens_over_base()]) + return iI + + def decomposition(self): + r""" + Return prime ideal decomposition of `pO_\infty` where `p` is the unique + prime ideal of the maximal infinite order of the rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = F.maximal_order_infinite() + sage: Oinf.decomposition() + [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), + (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] + + :: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.decomposition() + [(Ideal (1/x*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x, 1, 2)] + + :: + + sage: K. = FunctionField(QQ); _. = K[] + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) + sage: Oinf = F.maximal_order_infinite() + sage: Oinf.decomposition() + [(Ideal (1/x^2*y - 1) of Maximal infinite order + of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 1, 1), + (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order + of Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2, 2, 1)] + + :: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.decomposition() + [(Ideal (1/x*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x, 1, 2)] + """ + F = self.function_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + + x = iF.base_field().gen() + iO = iF.maximal_order() + io = iF.base_field().maximal_order() + ip = io.ideal(x) + + dec = [] + for iprime, deg, exp in iO.decomposition(ip): + prime = self.ideal_monoid().element_class(self, iprime) + dec.append((prime, deg, exp)) + return dec + + def different(self): + """ + Return the different ideal of the maximal infinite order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf.different() + Ideal (1/x) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + """ + T = self._codifferent_matrix() + codiff_gens = [] + for c in T.inverse().columns(): + codiff_gens.append(sum([ci*bi for ci,bi in zip(c,self.basis())])) + codiff = self.ideal_with_gens_over_base(codiff_gens) + return ~codiff + + @cached_method + def _codifferent_matrix(self): + """ + Return the codifferent matrix of the maximal infinite order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: Oinf._codifferent_matrix() + [ 0 1/x] + [ 1/x 1/x^2] + """ + from sage.matrix.constructor import matrix + + rows = [] + for u in self.basis(): + row = [] + for v in self.basis(): + row.append((u*v).trace()) + rows.append(row) + T = matrix(rows) + return T + + def coordinate_vector(self, e): + """ + Return the coordinates of ``e`` with respect to the basis of the order. + + INPUT: + + - ``e`` -- element of the function field + + The returned coordinates are in the base maximal infinite order if and only + if the element is in the order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: Oinf = L.maximal_order_infinite() + sage: f = 1/y^2 + sage: f in Oinf + True + sage: Oinf.coordinate_vector(f) + ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) + """ + return self._module.coordinate_vector(self._to_module(e)) diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py new file mode 100644 index 00000000000..4f36af13442 --- /dev/null +++ b/src/sage/rings/function_field/order_rational.py @@ -0,0 +1,562 @@ +# some tests are marked # optional - sage.libs.pari (because they use finite fields) +r""" +Orders of rational function fields +""" + +import sage.rings.abc + +from sage.arith.functions import lcm +from sage.arith.misc import GCD as gcd +from sage.categories.euclidean_domains import EuclideanDomains +from sage.categories.principal_ideal_domains import PrincipalIdealDomains +from sage.rings.number_field.number_field_base import NumberField + +from .ideal import ( + FunctionFieldIdeal, + FunctionFieldIdeal_rational, + FunctionFieldIdealInfinite_rational, +) +from .order import FunctionFieldMaximalOrder, FunctionFieldMaximalOrderInfinite + + +class FunctionFieldMaximalOrder_rational(FunctionFieldMaximalOrder): + """ + Maximal orders of rational function fields. + + INPUT: + + - ``field`` -- a function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari + Rational function field in t over Finite Field of size 19 + sage: R = K.maximal_order(); R # optional - sage.libs.pari + Maximal order of Rational function field in t over Finite Field of size 19 + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') + """ + FunctionFieldMaximalOrder.__init__(self, field, ideal_class=FunctionFieldIdeal_rational, + category=EuclideanDomains()) + + self._populate_coercion_lists_(coerce_list=[field._ring]) + + self._ring = field._ring + self._gen = self(self._ring.gen()) + self._basis = (self.one(),) + + def _element_constructor_(self, f): + """ + Make ``f`` a function field element of this order. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O._element_constructor_(y) + y + sage: O._element_constructor_(1/y) + Traceback (most recent call last): + ... + TypeError: 1/y is not an element of Maximal order of Rational function field in y over Rational Field + """ + F = self.function_field() + try: + f = F(f) + except TypeError: + raise TypeError("unable to convert to an element of {}".format(F)) + + if not f.denominator() in self.function_field().constant_base_field(): + raise TypeError("%r is not an element of %r"%(f,self)) + + return f + + def ideal_with_gens_over_base(self, gens): + """ + Return the fractional ideal with generators ``gens``. + + INPUT: + + - ``gens`` -- elements of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) # optional - sage.libs.singular + Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 + """ + return self.ideal(gens) + + def _residue_field(self, ideal, name=None): + """ + Return a field isomorphic to the residue field at the prime ideal. + + The residue field is by definition `k[x]/q` where `q` is the irreducible + polynomial generating the prime ideal and `k` is the constant base field. + + INPUT: + + - ``ideal`` -- prime ideal of the order + + - ``name`` -- string; name of the generator of the residue field + + OUTPUT: + + - a field isomorphic to the residue field + + - a morphism from the field to `k[x]` via the residue field + + - a morphism from `k[x]` to the field via the residue field + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Finite Field in z2 of size 2^2 + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari + [True, True, True, True] + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari + [True, True, True, True] + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari + True + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari + True + sage: to_R(e1).parent() is R # optional - sage.libs.pari + True + sage: to_R(e2).parent() is R # optional - sage.libs.pari + True + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x + 1) # optional - sage.libs.pari + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Finite Field of size 2 + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari + [True, True] + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari + [True, True] + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari + True + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari + True + sage: to_R(e1).parent() is R # optional - sage.libs.pari + True + sage: to_R(e2).parent() is R # optional - sage.libs.pari + True + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: I = O.ideal(x^2 + x + 1) + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.rings.number_field + sage: R # optional - sage.rings.number_field + Number Field in a with defining polynomial x^2 + x + 1 + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.rings.number_field + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.rings.number_field + True + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.rings.number_field + True + sage: to_R(e1).parent() is R # optional - sage.rings.number_field + True + sage: to_R(e2).parent() is R # optional - sage.rings.number_field + True + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: I = O.ideal(x + 1) + sage: R, fr_R, to_R = O._residue_field(I) + sage: R + Rational Field + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) + True + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) + True + sage: to_R(e1).parent() is R + True + sage: to_R(e2).parent() is R + True + """ + F = self.function_field() + K = F.constant_base_field() + + q = ideal.gen().element().numerator() + + if F.is_global(): + R, _from_R, _to_R = self._residue_field_global(q, name=name) + elif isinstance(K, (NumberField, sage.rings.abc.AlgebraicField)): + if name is None: + name = 'a' + if q.degree() == 1: + R = K + _from_R = lambda e: e + _to_R = lambda e: R(e % q) + else: + R = K.extension(q, names=name) + _from_R = lambda e: self._ring(list(R(e))) + _to_R = lambda e: (e % q)(R.gen(0)) + else: + raise NotImplementedError + + def from_R(e): + return F(_from_R(e)) + + def to_R(f): + return _to_R(f.numerator()) + + return R, from_R, to_R + + def _residue_field_global(self, q, name=None): + """ + Return a finite field isomorphic to the residue field at q. + + This method assumes a global rational function field, that is, + the constant base field is a finite field. + + INPUT: + + - ``q`` -- irreducible polynomial + + - ``name`` -- string; name of the generator of the extension field + + OUTPUT: + + - a finite field + + - a function that outputs a polynomial lifting a finite field element + + - a function that outputs a finite field element for a polynomial + + The residue field is by definition `k[x]/q` where `k` is the base field. + + EXAMPLES:: + + sage: k. = GF(4) # optional - sage.libs.pari + sage: F. = FunctionField(k) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O._ring # optional - sage.libs.pari + Univariate Polynomial Ring in x over Finite Field in a of size 2^2 + sage: f = x^3 + x + 1 # optional - sage.libs.pari + sage: _f = f.numerator() # optional - sage.libs.pari + sage: _f.is_irreducible() # optional - sage.libs.pari + True + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules + sage: K # optional - sage.libs.pari sage.modules + Finite Field in z6 of size 2^6 + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules + True + + sage: k. = GF(2) # optional - sage.libs.pari + sage: F. = FunctionField(k) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O._ring # optional - sage.libs.pari + Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) + sage: f = x^3 + x + 1 # optional - sage.libs.pari + sage: _f = f.numerator() # optional - sage.libs.pari + sage: _f.is_irreducible() # optional - sage.libs.pari + True + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules + True + + """ + # polynomial ring over the base field + R = self._ring + + # base field of extension degree r over the prime field + k = R.base_ring() + a = k.gen() + r = k.degree() + + # extend the base field to a field of degree r*s over the + # prime field + s = q.degree() + K,sigma = k.extension(s, map=True, name=name) + + # find a root beta in K satisfying the irreducible q + S = K['X'] + beta = S([sigma(c) for c in q.list()]).roots()[0][0] + + # V is a vector space over the prime subfield of k of degree r*s + V = K.vector_space(map=False) + + w = K.one() + beta_pow = [] + for i in range(s): + beta_pow.append(w) + w *= beta + + w = K.one() + sigma_a = sigma(a) + sigma_a_pow = [] + for i in range(r): + sigma_a_pow.append(w) + w *= sigma_a + + basis = [V(sap * bp) for bp in beta_pow for sap in sigma_a_pow] + W = V.span_of_basis(basis) + + def to_K(f): + coeffs = (f % q).list() + return sum((sigma(c) * beta_pow[i] for i, c in enumerate(coeffs)), K.zero()) + + if r == 1: # take care of the prime field case + def fr_K(g): + co = W.coordinates(V(g), check=False) + return R([k(co[j]) for j in range(s)]) + else: + def fr_K(g): + co = W.coordinates(V(g), check=False) + return R([k(co[i:i+r]) for i in range(0, r*s, r)]) + + return K, fr_K, to_K + + def basis(self): + """ + Return the basis (=1) of the order as a module over the polynomial ring. + + EXAMPLES:: + + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari + (1,) + """ + return self._basis + + def gen(self, n=0): + """ + Return the ``n``-th generator of the order. Since there is only one generator ``n`` must be 0. + + EXAMPLES:: + + sage: O = FunctionField(QQ,'y').maximal_order() + sage: O.gen() + y + sage: O.gen(1) + Traceback (most recent call last): + ... + IndexError: there is only one generator + """ + if n != 0: + raise IndexError("there is only one generator") + return self._gen + + def ngens(self): + """ + Return 1 the number of generators of the order. + + EXAMPLES:: + + sage: FunctionField(QQ,'y').maximal_order().ngens() + 1 + """ + return 1 + + def ideal(self, *gens): + """ + Return the fractional ideal generated by ``gens``. + + INPUT: + + - ``gens`` -- elements of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O.ideal(x) + Ideal (x) of Maximal order of Rational function field in x over Rational Field + sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list + True + sage: O.ideal(x^3+1,x^3+6) + Ideal (1) of Maximal order of Rational function field in x over Rational Field + sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I + Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field + sage: O.ideal(I) + Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field + """ + if len(gens) == 1: + gens = gens[0] + if not isinstance(gens, (list, tuple)): + if isinstance(gens, FunctionFieldIdeal): + gens = gens.gens() + else: + gens = (gens,) + K = self.function_field() + gens = [K(e) for e in gens if e != 0] + if len(gens) == 0: + gen = K(0) + else: + d = lcm([c.denominator() for c in gens]).monic() + g = gcd([(d*c).numerator() for c in gens]).monic() + gen = K(g/d) + + return self.ideal_monoid().element_class(self, gen) + + +class FunctionFieldMaximalOrderInfinite_rational(FunctionFieldMaximalOrderInfinite): + """ + Maximal infinite orders of rational function fields. + + INPUT: + + - ``field`` -- a rational function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari + Rational function field in t over Finite Field of size 19 + sage: R = K.maximal_order_infinite(); R # optional - sage.libs.pari + Maximal infinite order of Rational function field in t over Finite Field of size 19 + """ + def __init__(self, field, category=None): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order_infinite() # optional - sage.libs.pari + sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') # optional - sage.libs.pari + """ + FunctionFieldMaximalOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_rational, + category=PrincipalIdealDomains().or_subcategory(category)) + self._populate_coercion_lists_(coerce_list=[field.constant_base_field()]) + + def _element_constructor_(self, f): + """ + Make ``f`` an element of this order. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: O._element_constructor_(y) + y + sage: O._element_constructor_(1/y) + Traceback (most recent call last): + ... + TypeError: 1/y is not an element of Maximal order of Rational function field in y over Rational Field + """ + F = self.function_field() + try: + f = F(f) + except TypeError: + raise TypeError("unable to convert to an element of {}".format(F)) + + if f.denominator().degree() < f.numerator().degree(): + raise TypeError("{} is not an element of {}".format(f, self)) + + return f + + def basis(self): + """ + Return the basis (=1) of the order as a module over the polynomial ring. + + EXAMPLES:: + + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari + (1,) + """ + return 1/self.function_field().gen() + + def gen(self, n=0): + """ + Return the ``n``-th generator of self. Since there is only one generator ``n`` must be 0. + + EXAMPLES:: + + sage: O = FunctionField(QQ,'y').maximal_order() + sage: O.gen() + y + sage: O.gen(1) + Traceback (most recent call last): + ... + IndexError: there is only one generator + """ + if n != 0: + raise IndexError("there is only one generator") + return self._gen + + def ngens(self): + """ + Return 1 the number of generators of the order. + + EXAMPLES:: + + sage: FunctionField(QQ,'y').maximal_order().ngens() + 1 + """ + return 1 + + def prime_ideal(self): + """ + Return the unique prime ideal of the order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari + sage: O = K.maximal_order_infinite() # optional - sage.libs.pari + sage: O.prime_ideal() # optional - sage.libs.pari + Ideal (1/t) of Maximal infinite order of Rational function field in t + over Finite Field of size 19 + """ + return self.ideal( 1/self.function_field().gen() ) + + def ideal(self, *gens): + """ + Return the fractional ideal generated by ``gens``. + + INPUT: + + - ``gens`` -- elements of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order_infinite() + sage: O.ideal(x) + Ideal (x) of Maximal infinite order of Rational function field in x over Rational Field + sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list + True + sage: O.ideal(x^3+1,x^3+6) + Ideal (x^3) of Maximal infinite order of Rational function field in x over Rational Field + sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I + Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field + sage: O.ideal(I) + Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field + """ + if len(gens) == 1: + gens = gens[0] + if not isinstance(gens, (list, tuple)): + if isinstance(gens, FunctionFieldIdeal): + gens = gens.gens() + else: + gens = (gens,) + K = self.function_field() + gens = [K(g) for g in gens] + try: + d = max(g.numerator().degree() - g.denominator().degree() for g in gens if g != 0) + gen = K.gen() ** d + except ValueError: # all gens are zero + gen = K(0) + + return self.ideal_monoid().element_class(self, gen) From e6c197e153393021315a1f3f6437819e606fe19c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 14 Mar 2023 18:20:32 +0900 Subject: [PATCH 23/54] Split off _rational modules --- src/sage/rings/derivation.py | 9 +- src/sage/rings/fraction_field.py | 2 +- src/sage/rings/function_field/constructor.py | 21 +- src/sage/rings/function_field/derivations.py | 996 ----- src/sage/rings/function_field/element.pyx | 865 ---- .../rings/function_field/function_field.py | 3501 +---------------- .../function_field_valuation.py | 1482 ------- src/sage/rings/function_field/ideal.py | 2445 +----------- src/sage/rings/function_field/order.py | 4 +- src/sage/rings/function_field/order_basis.py | 8 + src/sage/rings/function_field/order_global.py | 363 -- .../rings/function_field/order_polymod.py | 372 +- .../rings/function_field/order_rational.py | 17 +- src/sage/rings/function_field/place.py | 817 +--- .../polynomial_singular_interface.py | 4 +- .../rings/valuation/valuations_catalog.py | 2 +- 16 files changed, 501 insertions(+), 10407 deletions(-) delete mode 100644 src/sage/rings/function_field/function_field_valuation.py delete mode 100644 src/sage/rings/function_field/order_global.py diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index c2ef53ebba1..4c8cb4662b9 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -196,7 +196,8 @@ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic from sage.rings.padics.padic_generic import pAdicGeneric -from sage.rings.function_field.function_field import FunctionField, RationalFunctionField +from sage.rings.function_field.function_field import FunctionField +from sage.rings.function_field.function_field_rational import RationalFunctionField from sage.categories.number_fields import NumberFields from sage.categories.finite_fields import FiniteFields from sage.categories.modules import Modules @@ -391,13 +392,13 @@ def __init__(self, domain, codomain, twist=None): constants, sharp = self._base_derivation._constants self._constants = (constants, False) # can we do better? elif isinstance(domain, RationalFunctionField): - from sage.rings.function_field.derivations import FunctionFieldDerivation_rational + from sage.rings.function_field.derivations_rational import FunctionFieldDerivation_rational self.Element = FunctionFieldDerivation_rational self._gens = self._basis = [ None ] self._dual_basis = [ domain.gen() ] elif isinstance(domain, FunctionField): if domain.is_separable(): - from sage.rings.function_field.derivations import FunctionFieldDerivation_separable + from sage.rings.function_field.derivations_polymod import FunctionFieldDerivation_separable self._base_derivation = RingDerivationModule(domain.base_ring(), defining_morphism) self.Element = FunctionFieldDerivation_separable try: @@ -410,7 +411,7 @@ def __init__(self, domain, codomain, twist=None): except NotImplementedError: pass else: - from sage.rings.function_field.derivations import FunctionFieldDerivation_inseparable + from sage.rings.function_field.derivations_polymod import FunctionFieldDerivation_inseparable M, f, self._t = domain.separable_model() self._base_derivation = RingDerivationModule(M, defining_morphism * f) self._d = self._base_derivation(None) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index 3f1964b13d2..02805d36142 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -1056,7 +1056,7 @@ def _coerce_map_from_(self, R): 1/t """ - from sage.rings.function_field.function_field import RationalFunctionField + from sage.rings.function_field.function_field_rational import RationalFunctionField if isinstance(R, RationalFunctionField) and self.variable_name() == R.variable_name() and self.base_ring() is R.constant_base_field(): from sage.categories.homset import Hom parent = Hom(R, self) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index 8fc3b44c7b3..457530a5dd0 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -99,13 +99,13 @@ def create_object(self, version, key,**extra_args): True """ if key[0].is_finite(): - from .function_field import RationalFunctionField_global + from .function_field_rational import RationalFunctionField_global return RationalFunctionField_global(key[0], names=key[1]) elif key[0].characteristic() == 0: - from .function_field import RationalFunctionField_char_zero + from .function_field_rational import RationalFunctionField_char_zero return RationalFunctionField_char_zero(key[0], names=key[1]) else: - from .function_field import RationalFunctionField + from .function_field_rational import RationalFunctionField return RationalFunctionField(key[0], names=key[1]) FunctionField=FunctionFieldFactory("sage.rings.function_field.constructor.FunctionField") @@ -185,26 +185,27 @@ def create_object(self,version,key,**extra_args): sage: L is M # optional - sage.libs.singular True """ - from . import function_field + from . import function_field_polymod, function_field_rational + f = key[0] names = key[1] base_field = f.base_ring() - if isinstance(base_field, function_field.RationalFunctionField): + if isinstance(base_field, function_field_rational.RationalFunctionField): k = base_field.constant_field() if k.is_finite(): # then we are in positive characteristic # irreducible and separable if f.is_irreducible() and not all(e % k.characteristic() == 0 for e in f.exponents()): # monic and integral if f.is_monic() and all(e in base_field.maximal_order() for e in f.coefficients()): - return function_field.FunctionField_global_integral(f, names) + return function_field_polymod.FunctionField_global_integral(f, names) else: - return function_field.FunctionField_global(f, names) + return function_field_polymod.FunctionField_global(f, names) elif k.characteristic() == 0: if f.is_irreducible() and f.is_monic() and all(e in base_field.maximal_order() for e in f.coefficients()): - return function_field.FunctionField_char_zero_integral(f, names) + return function_field_polymod.FunctionField_char_zero_integral(f, names) else: - return function_field.FunctionField_char_zero(f, names) - return function_field.FunctionField_polymod(f, names) + return function_field_polymod.FunctionField_char_zero(f, names) + return function_field_polymod.FunctionField_polymod(f, names) FunctionFieldExtension = FunctionFieldExtensionFactory( "sage.rings.function_field.constructor.FunctionFieldExtension") diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index 70062ce1fea..4a088e781fb 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -21,10 +21,6 @@ """ -from sage.arith.misc import binomial -from sage.categories.homset import Hom -from sage.categories.map import Map -from sage.categories.sets_cat import Sets from sage.rings.derivation import RingDerivationWithoutTwist @@ -90,995 +86,3 @@ def _rmul_(self, factor): return self._lmul_(factor) -class FunctionFieldDerivation_rational(FunctionFieldDerivation): - """ - Derivations on rational function fields. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.derivation() - d/dx - """ - def __init__(self, parent, u=None): - """ - Initialize a derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``u`` -- a parameter describing the derivation - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: TestSuite(d).run() - - The parameter ``u`` can be the name of the variable:: - - sage: K.derivation(x) - d/dx - - or a list of length one whose unique element is the image - of the generator of the underlying function field:: - - sage: K.derivation([x^2]) - x^2*d/dx - """ - FunctionFieldDerivation.__init__(self, parent) - if u is None or u == parent.domain().gen(): - self._u = parent.codomain().one() - elif u == 0 or isinstance(u, (list, tuple)): - if u == 0 or len(u) == 0: - self._u = parent.codomain().zero() - elif len(u) == 1: - self._u = parent.codomain()(u[0]) - else: - raise ValueError("the length does not match") - else: - raise ValueError("you must pass in either a name of a variable or a list of coefficients") - - def _call_(self, x): - """ - Compute the derivation of ``x``. - - INPUT: - - - ``x`` -- element of the rational function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d(x) # indirect doctest - 1 - sage: d(x^3) - 3*x^2 - sage: d(1/x) - -1/x^2 - """ - f = x.numerator() - g = x.denominator() - numerator = f.derivative() * g - f * g.derivative() - if numerator.is_zero(): - return self.codomain().zero() - else: - v = numerator / g**2 - defining_morphism = self.parent()._defining_morphism - if defining_morphism is not None: - v = defining_morphism(v) - return self._u * v - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d + d - 2*d/dx - """ - return type(self)(self.parent(), [self._u + other._u]) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: d = K.derivation() - sage: d - d/dx - sage: x * d - x*d/dx - """ - return type(self)(self.parent(), [factor * self._u]) - - -class FunctionFieldDerivation_separable(FunctionFieldDerivation): - """ - Derivations of separable extensions. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: L.derivation() - d/dx - """ - def __init__(self, parent, d): - """ - Initialize a derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``d`` -- a variable name or a derivation over - the base field (or something capable to create - such a derivation) - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: TestSuite(d).run() - - sage: L.derivation(y) # d/dy - 2*y*d/dx - - sage: dK = K.derivation([x]); dK - x*d/dx - sage: L.derivation(dK) - x*d/dx - """ - FunctionFieldDerivation.__init__(self, parent) - L = parent.domain() - C = parent.codomain() - dm = parent._defining_morphism - u = L.gen() - if d == L.gen(): - d = parent._base_derivation(None) - f = L.polynomial().change_ring(L) - coeff = -f.derivative()(u) / f.map_coefficients(d)(u) - if dm is not None: - coeff = dm(coeff) - self._d = parent._base_derivation([coeff]) - self._gen_image = C.one() - else: - if isinstance(d, RingDerivationWithoutTwist) and d.domain() is L.base_ring(): - self._d = d - else: - self._d = d = parent._base_derivation(d) - f = L.polynomial() - if dm is None: - denom = f.derivative()(u) - else: - u = dm(u) - denom = f.derivative().map_coefficients(dm, new_base_ring=C)(u) - num = f.map_coefficients(d, new_base_ring=C)(u) - self._gen_image = -num / denom - - def _call_(self, x): - r""" - Evaluate the derivation on ``x``. - - INPUT: - - - ``x`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d(x) # indirect doctest - 1 - sage: d(y) - 1/2/x*y - sage: d(y^2) - 1 - """ - parent = self.parent() - if x.is_zero(): - return parent.codomain().zero() - x = x._x - y = parent.domain().gen() - dm = parent._defining_morphism - tmp1 = x.map_coefficients(self._d, new_base_ring=parent.codomain()) - tmp2 = x.derivative()(y) - if dm is not None: - tmp2 = dm(tmp2) - y = dm(y) - return tmp1(y) + tmp2 * self._gen_image - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d - d/dx - sage: d + d - 2*d/dx - """ - return type(self)(self.parent(), self._d + other._d) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) - sage: d = L.derivation() - sage: d - d/dx - sage: y * d - y*d/dx - """ - return type(self)(self.parent(), factor * self._d) - - -class FunctionFieldDerivation_inseparable(FunctionFieldDerivation): - def __init__(self, parent, u=None): - r""" - Initialize this derivation. - - INPUT: - - - ``parent`` -- the parent of this derivation - - - ``u`` -- a parameter describing the derivation - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - - This also works for iterated non-monic extensions:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari - sage: M.derivation() # optional - sage.libs.pari - d/dz - - We can also create a multiple of the canonical derivation:: - - sage: M.derivation([x]) # optional - sage.libs.pari - x*d/dz - """ - FunctionFieldDerivation.__init__(self, parent) - if u is None: - self._u = parent.codomain().one() - elif u == 0 or isinstance(u, (list, tuple)): - if u == 0 or len(u) == 0: - self._u = parent.codomain().zero() - elif len(u) == 1: - self._u = parent.codomain()(u[0]) - else: - raise ValueError("the length does not match") - else: - raise ValueError("you must pass in either a name of a variable or a list of coefficients") - - def _call_(self, x): - r""" - Evaluate the derivation on ``x``. - - INPUT: - - - ``x`` -- an element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d(x) # indirect doctest # optional - sage.libs.pari - 0 - sage: d(y) # optional - sage.libs.pari - 1 - sage: d(y^2) # optional - sage.libs.pari - 0 - - """ - if x.is_zero(): - return self.codomain().zero() - parent = self.parent() - return self._u * parent._d(parent._t(x)) - - def _add_(self, other): - """ - Return the sum of this derivation and ``other``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari - d/dy - sage: d + d # optional - sage.libs.pari - 2*d/dy - """ - return type(self)(self.parent(), [self._u + other._u]) - - def _lmul_(self, factor): - """ - Return the product of this derivation by the scalar ``factor``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari - d/dy - sage: y * d # optional - sage.libs.pari - y*d/dy - """ - return type(self)(self.parent(), [factor * self._u]) - - -class FunctionFieldHigherDerivation(Map): - """ - Base class of higher derivations on function fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.higher_derivation() # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari - """ - Map.__init__(self, Hom(field, field, Sets())) - self._field = field - # elements of a prime finite field do not have pth_root method - if field.constant_base_field().is_prime_field(): - self._pth_root_func = _pth_root_in_prime_field - else: - self._pth_root_func = _pth_root_in_finite_field - - def _repr_type(self) -> str: - """ - Return a string containing the type of the map. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # indirect doctest # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - """ - return 'Higher derivation' - - def __eq__(self, other) -> bool: - """ - Test if ``self`` equals ``other``. - - TESTS:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: loads(dumps(h)) == h # optional - sage.libs.pari - True - """ - if isinstance(other, FunctionFieldHigherDerivation): - return self._field == other._field - return False - - -def _pth_root_in_prime_field(e): - """ - Return the `p`-th root of element ``e`` in a prime finite field. - - TESTS:: - - sage: from sage.rings.function_field.derivations import _pth_root_in_prime_field - sage: p = 5 - sage: F. = GF(p) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari - True - """ - return e - - -def _pth_root_in_finite_field(e): - """ - Return the `p`-th root of element ``e`` in a finite field. - - TESTS:: - - sage: from sage.rings.function_field.derivations import _pth_root_in_finite_field - sage: p = 3 - sage: F. = GF(p^2) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari - True - """ - return e.pth_root() - - -class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): - """ - Higher derivations of rational function fields over finite fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari - Higher derivation map: - From: Rational function field in x over Finite Field of size 2 - To: Rational function field in x over Finite Field of size 2 - sage: h(x^2,2) # optional - sage.libs.pari - 1 - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari - """ - FunctionFieldHigherDerivation.__init__(self, field) - - self._p = field.characteristic() - self._separating_element = field.gen() - - def _call_with_args(self, f, args=(), kwds={}): - """ - Call the derivation with args and kwds. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari - 1 - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return the `i`-th derivative of ``f`` with respect to the - separating element. - - This implements Hess' Algorithm 26 in [Hes2002b]_. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._derive(x^3,0) # optional - sage.libs.pari - x^3 - sage: h._derive(x^3,1) # optional - sage.libs.pari - x^2 - sage: h._derive(x^3,2) # optional - sage.libs.pari - x - sage: h._derive(x^3,3) # optional - sage.libs.pari - 1 - sage: h._derive(x^3,4) # optional - sage.libs.pari - 0 - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - prime_power_representation = self._prime_power_representation - - def derive(f, i): - # Step 1: zero-th derivative - if i == 0: - return f - # Step 2: - s = i % p - r = i // p - # Step 3: - e = f - while s > 0: - e = derivative(e) / F(s) - s -= 1 - # Step 4: - if r == 0: - return e - else: - # Step 5: - lambdas = prime_power_representation(e, x) - # Step 6 and 7: - der = 0 - for i in range(p): - mu = derive(lambdas[i], r) - der += mu**p * x**i - return der - - return derive(f, i) - - def _prime_power_representation(self, f, separating_element=None): - """ - Return `p`-th power representation of the element ``f``. - - Here `p` is the characteristic of the function field. - - This implements Hess' Algorithm 25. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari - [x + 1, 1] - sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari - True - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - # Step 1: - a = [f] - aprev = f - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - # Step 2: - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) - for i in range(j + 1, p)) - j -= 1 - # Step 3 - return [self._pth_root(c) for c in b] - - def _pth_root(self, c): - """ - Return the `p`-th root of the rational function ``c``. - - INPUT: - - - ``c`` -- rational function - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari - x^2 + 1 - """ - K = self._field - p = self._p - - R = K._field.ring() - - poly = c.numerator() - num = R([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - poly = c.denominator() - den = R([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - return K.element_class(K, num / den) - - -class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): - """ - Higher derivations of global function fields. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari sage.modules - Higher derivation map: - From: Function field in y defined by y^3 + x^3*y + x - To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) # optional - sage.libs.pari sage.modules - ((x^7 + 1)/x^2)*y^2 + x^3*y - """ - - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari sage.modules - """ - from sage.matrix.constructor import matrix - - FunctionFieldHigherDerivation.__init__(self, field) - - self._p = field.characteristic() - self._separating_element = field(field.base_field().gen()) - - p = field.characteristic() - y = field.gen() - - # matrix for pth power map; used in _prime_power_representation method - self.__pth_root_matrix = matrix([(y**(i * p)).list() - for i in range(field.degree())]).transpose() - - # cache computed higher derivatives to speed up later computations - self._cache = {} - - def _call_with_args(self, f, args, kwds): - """ - Call the derivation with ``args`` and ``kwds``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari sage.modules - ((x^7 + 1)/x^2)*y^2 + x^3*y - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return ``i``-th derivative of ``f`` with respect to the separating - element. - - This implements Hess' Algorithm 26 in [Hes2002b]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: y^3 # optional - sage.libs.pari sage.modules - x^3*y + x - sage: h._derive(y^3,0) # optional - sage.libs.pari sage.modules - x^3*y + x - sage: h._derive(y^3,1) # optional - sage.libs.pari sage.modules - x^4*y^2 + 1 - sage: h._derive(y^3,2) # optional - sage.libs.pari sage.modules - x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) # optional - sage.libs.pari sage.modules - (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) # optional - sage.libs.pari sage.modules - (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y - """ - F = self._field - p = self._p - frob = F.frobenius_endomorphism() # p-th power map - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - try: - cache = self._cache[separating_element] - except KeyError: - cache = self._cache[separating_element] = {} - - def derive(f, i): - # Step 1: zero-th derivative - if i == 0: - return f - - # Step 1.5: use cached result if available - try: - return cache[f, i] - except KeyError: - pass - - # Step 2: - s = i % p - r = i // p - # Step 3: - e = f - while s > 0: - e = derivative(e) / F(s) - s -= 1 - # Step 4: - if r == 0: - der = e - else: - # Step 5: inlined self._prime_power_representation - a = [e] - aprev = e - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(k, j) * b[k] * x**(k - j) - for k in range(j + 1, p)) - j -= 1 - lambdas = [self._pth_root(c) for c in b] - - # Step 6 and 7: - der = 0 - xpow = 1 - for k in range(p): - mu = derive(lambdas[k], r) - der += frob(mu) * xpow - xpow *= x - - cache[f, i] = der - return der - - return derive(f, i) - - def _prime_power_representation(self, f, separating_element=None): - """ - Return `p`-th power representation of the element ``f``. - - Here `p` is the characteristic of the function field. - - This implements Hess' Algorithm 25 in [Hes2002b]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: b = h._prime_power_representation(y) # optional - sage.libs.pari sage.modules - sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari sage.modules - True - """ - F = self._field - p = self._p - - if separating_element is None: - x = self._separating_element - - def derivative(f): - return f.derivative() - else: - x = separating_element - xderinv = ~(x.derivative()) - - def derivative(f): - return xderinv * f.derivative() - - # Step 1: - a = [f] - aprev = f - j = 1 - while j < p: - aprev = derivative(aprev) / F(j) - a.append(aprev) - j += 1 - # Step 2: - b = a - j = p - 2 - while j >= 0: - b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) - for i in range(j + 1, p)) - j -= 1 - # Step 3 - return [self._pth_root(c) for c in b] - - def _pth_root(self, c): - """ - Return the `p`-th root of function field element ``c``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari sage.modules - y^2 + x^2 - """ - from sage.modules.free_module_element import vector - - K = self._field.base_field() # rational function field - p = self._p - - coeffs = [] - for d in self.__pth_root_matrix.solve_right(vector(c.list())): - poly = d.numerator() - num = K([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - poly = d.denominator() - den = K([self._pth_root_func(poly[i]) - for i in range(0, poly.degree() + 1, p)]) - coeffs.append(num / den) - return self._field(coeffs) - - -class FunctionFieldHigherDerivation_char_zero(FunctionFieldHigherDerivation): - """ - Higher derivations of function fields of characteristic zero. - - INPUT: - - - ``field`` -- function field on which the derivation operates - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: h - Higher derivation map: - From: Function field in y defined by y^3 + x^3*y + x - To: Function field in y defined by y^3 + x^3*y + x - sage: h(y,1) == -(3*x^2*y+1)/(3*y^2+x^3) - True - sage: h(y^2,1) == -2*y*(3*x^2*y+1)/(3*y^2+x^3) - True - sage: e = L.random_element() - sage: h(h(e,1),1) == 2*h(e,2) - True - sage: h(h(h(e,1),1),1) == 3*2*h(e,3) - True - """ - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: TestSuite(h).run(skip=['_test_category']) - """ - FunctionFieldHigherDerivation.__init__(self, field) - - self._separating_element = field(field.base_field().gen()) - - # cache computed higher derivatives to speed up later computations - self._cache = {} - - def _call_with_args(self, f, args, kwds): - """ - Call the derivation with ``args`` and ``kwds``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: e = L.random_element() - sage: h(h(e,1),1) == 2*h(e,2) # indirect doctest - True - """ - return self._derive(f, *args, **kwds) - - def _derive(self, f, i, separating_element=None): - """ - Return ``i``-th derivative of ``f`` with respect to the separating - element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: h = L.higher_derivation() - sage: y^3 - -x^3*y - x - sage: h._derive(y^3,0) - -x^3*y - x - sage: h._derive(y^3,1) - (-21/4*x^4/(x^7 + 27/4))*y^2 + ((-9/2*x^9 - 45/2*x^2)/(x^7 + 27/4))*y + (-9/2*x^7 - 27/4)/(x^7 + 27/4) - """ - F = self._field - - if separating_element is None: - x = self._separating_element - xderinv = 1 - else: - x = separating_element - xderinv = ~(x.derivative()) - - try: - cache = self._cache[separating_element] - except KeyError: - cache = self._cache[separating_element] = {} - - if i == 0: - return f - - try: - return cache[f, i] - except KeyError: - pass - - s = i - e = f - while s > 0: - e = xderinv * e.derivative() / F(s) - s -= 1 - - der = e - - cache[f, i] = der - return der diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 5555e73c904..cd06093ba84 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -104,9 +104,6 @@ cdef class FunctionFieldElement(FieldElement): sage: isinstance(t, sage.rings.function_field.element.FunctionFieldElement) True """ - cdef readonly object _x - cdef readonly object _matrix - def __reduce__(self): """ EXAMPLES:: @@ -716,865 +713,3 @@ cdef class FunctionFieldElement(FieldElement): """ raise NotImplementedError("nth_root() not implemented for generic elements") -cdef class FunctionFieldElement_polymod(FunctionFieldElement): - """ - Elements of a finite extension of a function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: x*y + 1/x^3 # optional - sage.libs.singular - x*y + 1/x^3 - """ - def __init__(self, parent, x, reduce=True): - """ - Initialize. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: TestSuite(x*y + 1/x^3).run() # optional - sage.libs.singular - """ - FieldElement.__init__(self, parent) - if reduce: - self._x = x % self._parent.polynomial() - else: - self._x = x - - def element(self): - """ - Return the underlying polynomial that represents the element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(T^2 - x*T + 4*x^3) # optional - sage.libs.singular - sage: f = y/x^2 + x/(x^2+1); f # optional - sage.libs.singular - 1/x^2*y + x/(x^2 + 1) - sage: f.element() # optional - sage.libs.singular - 1/x^2*y + x/(x^2 + 1) - """ - return self._x - - def _repr_(self): - """ - Return the string representation of the element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y._repr_() # optional - sage.libs.singular - 'y' - """ - return self._x._repr(name=self.parent().variable_name()) - - def __bool__(self): - """ - Return True if the element is not zero. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: bool(y) # optional - sage.libs.singular - True - sage: bool(L(0)) # optional - sage.libs.singular - False - sage: bool(L.coerce(L.polynomial())) # optional - sage.libs.singular - False - """ - return not not self._x - - def __hash__(self): - """ - Return the hash of the element. - - TESTS:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 # optional - sage.libs.singular - True - """ - return hash(self._x) - - cpdef _richcmp_(self, other, int op): - """ - Do rich comparison with the other element with respect to ``op`` - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: L(0) == 0 # optional - sage.libs.singular - True - sage: y != L(2) # optional - sage.libs.singular - True - """ - cdef FunctionFieldElement left = self - cdef FunctionFieldElement right = other - return richcmp(left._x, right._x, op) - - cpdef _add_(self, right): - """ - Add the element with the other element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular - (5*x + 5)*y + x/(x^3 + 1) - sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest # optional - sage.libs.singular - True - sage: -y + y # optional - sage.libs.singular - 0 - """ - cdef FunctionFieldElement res = self._new_c() - res._x = self._x + (right)._x - return res - - cpdef _sub_(self, right): - """ - Subtract the other element from the element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular - (-5*x - 1)*y + x/(x^3 + 1) - sage: y - y # optional - sage.libs.singular - 0 - """ - cdef FunctionFieldElement res = self._new_c() - res._x = self._x - (right)._x - return res - - cpdef _mul_(self, right): - """ - Multiply the element with the other element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y * (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular - (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3 - """ - cdef FunctionFieldElement res = self._new_c() - res._x = (self._x * (right)._x) % self._parent.polynomial() - return res - - cpdef _div_(self, right): - """ - Divide the element with the other element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest # optional - sage.libs.singular - 1 - sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest # optional - sage.libs.singular - Traceback (most recent call last): - ... - ZeroDivisionError: Cannot invert 0 - """ - return self * ~right - - def __invert__(self): - """ - Return the multiplicative inverse of the element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: a = ~(2*y + 1/x); a # indirect doctest # optional - sage.libs.singular - (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a*(2*y + 1/x) # optional - sage.libs.singular - 1 - """ - if self.is_zero(): - raise ZeroDivisionError("Cannot invert 0") - P = self._parent - return P(self._x.xgcd(P._polynomial)[1]) - - cpdef list list(self): - """ - Return the list of the coefficients representing the element. - - If the function field is `K[y]/(f(y))`, then return the coefficients of - the reduced presentation of the element as a polynomial in `K[y]`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: a = ~(2*y + 1/x); a # optional - sage.libs.singular - (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a.list() # optional - sage.libs.singular - [(1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16), -1/8*x^2/(x^5 + 1/8*x^2 + 1/16)] - sage: (x*y).list() # optional - sage.libs.singular - [0, x] - """ - return self._x.padded_list(self._parent.degree()) - - cpdef FunctionFieldElement nth_root(self, n): - r""" - Return an ``n``-th root of this element in the function field. - - INPUT: - - - ``n`` -- an integer - - OUTPUT: - - Returns an element ``a`` in the function field such that this element - equals `a^n`. Raises an error if no such element exists. - - ALGORITHM: - - If ``n`` is a power of the characteristic of the field and the constant - base field is perfect, then this uses the algorithm described in - Proposition 12 of [GiTr1996]_. - - .. SEEALSO:: - - :meth:`is_nth_power` - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L(y^3).nth_root(3) # optional - sage.libs.pari - y - sage: L(y^9).nth_root(-9) # optional - sage.libs.pari - 1/x*y - - This also works for inseparable extensions:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - x^2) # optional - sage.libs.pari - sage: L(x).nth_root(3)^3 # optional - sage.libs.pari - x - sage: L(x^9).nth_root(-27)^-27 # optional - sage.libs.pari - x^9 - - """ - if n == 1: - return self - if n < 0: - return (~self).nth_root(-n) - if n == 0: - if not self.is_one(): - raise ValueError("element is not a 0-th power") - return self - - # reduce to the separable case - poly = self._parent._polynomial - if not poly.gcd(poly.derivative()).is_one(): - L, from_L, to_L = self._parent.separable_model(('t', 'w')) - return from_L(to_L(self).nth_root(n)) - - constant_base_field = self._parent.constant_base_field() - p = constant_base_field.characteristic() - if p.divides(n) and constant_base_field.is_perfect(): - return self._pth_root().nth_root(n//p) - - raise NotImplementedError("nth_root() not implemented for this n") - - cpdef bint is_nth_power(self, n): - r""" - Return whether this element is an ``n``-th power in the function field. - - INPUT: - - - ``n`` -- an integer - - ALGORITHM: - - If ``n`` is a power of the characteristic of the field and the constant - base field is perfect, then this uses the algorithm described in - Proposition 12 of [GiTr1996]_. - - .. SEEALSO:: - - :meth:`nth_root` - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: y.is_nth_power(2) # optional - sage.libs.pari - False - sage: L(x).is_nth_power(2) # optional - sage.libs.pari - True - - """ - if n == 0: - return self.is_one() - if n == 1: - return True - if n < 0: - return self.is_unit() and (~self).is_nth_power(-n) - - # reduce to the separable case - poly = self._parent._polynomial - if not poly.gcd(poly.derivative()).is_one(): - L, from_L, to_L = self._parent.separable_model(('t', 'w')) - return to_L(self).is_nth_power(n) - - constant_base_field = self._parent.constant_base_field() - p = constant_base_field.characteristic() - if p.divides(n) and constant_base_field.is_perfect(): - return self._parent.derivation()(self).is_zero() and self._pth_root().is_nth_power(n//p) - - raise NotImplementedError("is_nth_power() not implemented for this n") - - cdef FunctionFieldElement _pth_root(self): - r""" - Helper method for :meth:`nth_root` and :meth:`is_nth_power` which - computes a `p`-th root if the characteristic is `p` and the constant - base field is perfect. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: (y^3).nth_root(3) # indirect doctest # optional - sage.libs.pari - y - """ - cdef Py_ssize_t deg = self._parent.degree() - if deg == 1: - return self._parent(self._x[0].nth_root(self._parent.characteristic())) - - from .function_field import RationalFunctionField - if not isinstance(self.base_ring(), RationalFunctionField): - raise NotImplementedError("only implemented for simple extensions of function fields") - # compute a representation of the generator y of the field in terms of powers of y^p - cdef Py_ssize_t i - cdef list v = [] - char = self._parent.characteristic() - cdef FunctionFieldElement_polymod yp = self._parent.gen() ** char - val = self._parent.one()._x - poly = self._parent.polynomial() - for i in range(deg): - v += val.padded_list(deg) - val = (val * yp._x) % poly - from sage.matrix.matrix_space import MatrixSpace - MS = MatrixSpace(self._parent._base, deg) - M = MS(v) - y = self._parent._base.polynomial_ring()(M.solve_left(MS.column_space()([0,1]+[0]*(deg-2))).list()) - - f = self._x(y).map_coefficients(lambda c: c.nth_root(char)) - return self._parent(f) - - -cdef class FunctionFieldElement_rational(FunctionFieldElement): - """ - Elements of a rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); K - Rational function field in t over Rational Field - sage: t^2 + 3/2*t - t^2 + 3/2*t - sage: FunctionField(QQ,'t').gen()^3 - t^3 - """ - def __init__(self, parent, x, reduce=True): - """ - Initialize. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: x = t^3 - sage: TestSuite(x).run() - """ - FieldElement.__init__(self, parent) - self._x = x - - def __pari__(self): - r""" - Coerce the element to PARI. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: ((a+1)/(a-1)).__pari__() # optional - sage.libs.pari - (a + 1)/(a - 1) - - """ - return self.element().__pari__() - - def element(self): - """ - Return the underlying fraction field element that represents the element. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: t.element() # optional - sage.libs.pari - t - sage: type(t.element()) # optional - sage.libs.pari - <... 'sage.rings.fraction_field_FpT.FpTElement'> - - sage: K. = FunctionField(GF(131101)) # optional - sage.libs.pari - sage: t.element() # optional - sage.libs.pari - t - sage: type(t.element()) # optional - sage.libs.pari - <... 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'> - """ - return self._x - - cpdef list list(self): - """ - Return a list with just the element. - - The list represents the element when the rational function field is - viewed as a (one-dimensional) vector space over itself. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t.list() - [t] - """ - return [self] - - def _repr_(self): - """ - Return the string representation of the element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t._repr_() - 't' - """ - return repr(self._x) - - def __bool__(self): - """ - Return True if the element is not zero. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: bool(t) - True - sage: bool(K(0)) - False - sage: bool(K(1)) - True - """ - return not not self._x - - def __hash__(self): - """ - Return the hash of the element. - - TESTS: - - It would be nice if the following would produce a list of - 15 distinct hashes:: - - sage: K. = FunctionField(QQ) - sage: len({hash(t^i+t^j) for i in [-2..2] for j in [i..2]}) >= 10 - True - """ - return hash(self._x) - - cpdef _richcmp_(self, other, int op): - """ - Compare the element with the other element with respect to ``op`` - - INPUT: - - - ``other`` -- element - - - ``op`` -- comparison operator - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t > 0 - True - sage: t < t^2 - True - """ - cdef FunctionFieldElement left - cdef FunctionFieldElement right - try: - left = self - right = other - lp = left._parent - rp = right._parent - if lp != rp: - return richcmp_not_equal(lp, rp, op) - return richcmp(left._x, right._x, op) - except TypeError: - return NotImplemented - - cpdef _add_(self, right): - """ - Add the element with the other element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t + (3*t^3) # indirect doctest - 3*t^3 + t - """ - cdef FunctionFieldElement res = self._new_c() - res._x = self._x + (right)._x - return res - - cpdef _sub_(self, right): - """ - Subtract the other element from the element. - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t - (3*t^3) # indirect doctest - -3*t^3 + t - """ - cdef FunctionFieldElement res = self._new_c() - res._x = self._x - (right)._x - return res - - cpdef _mul_(self, right): - """ - Multiply the element with the other element - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: (t+1) * (t^2-1) # indirect doctest - t^3 + t^2 - t - 1 - """ - cdef FunctionFieldElement res = self._new_c() - res._x = self._x * (right)._x - return res - - cpdef _div_(self, right): - """ - Divide the element with the other element - - INPUT: - - - ``right`` -- element - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: (t+1) / (t^2 - 1) # indirect doctest - 1/(t - 1) - """ - cdef FunctionFieldElement res = self._new_c() - res._parent = self._parent.fraction_field() - res._x = self._x / (right)._x - return res - - def numerator(self): - """ - Return the numerator of the rational function. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = (t+1) / (t^2 - 1/3); f - (t + 1)/(t^2 - 1/3) - sage: f.numerator() - t + 1 - """ - return self._x.numerator() - - def denominator(self): - """ - Return the denominator of the rational function. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = (t+1) / (t^2 - 1/3); f - (t + 1)/(t^2 - 1/3) - sage: f.denominator() - t^2 - 1/3 - """ - return self._x.denominator() - - def valuation(self, place): - """ - Return the valuation of the rational function at the place. - - Rational function field places are associated with irreducible - polynomials. - - INPUT: - - - ``place`` -- a place or an irreducible polynomial - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = (t - 1)^2*(t + 1)/(t^2 - 1/3)^3 - sage: f.valuation(t - 1) - 2 - sage: f.valuation(t) - 0 - sage: f.valuation(t^2 - 1/3) - -3 - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: p = K.places_finite()[0] # optional - sage.libs.pari - sage: (1/x^2).valuation(p) # optional - sage.libs.pari - -2 - """ - from .place import FunctionFieldPlace - - if not isinstance(place, FunctionFieldPlace): - # place is an irreducible polynomial - R = self._parent._ring - return self._x.valuation(R(self._parent(place)._x)) - - prime = place.prime_ideal() - ideal = prime.ring().ideal(self) - return prime.valuation(ideal) - - def is_square(self): - """ - Return whether the element is a square. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: t.is_square() - False - sage: (t^2/4).is_square() - True - sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square() - True - - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: (-t^2).is_square() # optional - sage.libs.pari - True - sage: (-t^2).sqrt() # optional - sage.libs.pari - 2*t - """ - return self._x.is_square() - - def sqrt(self, all=False): - """ - Return the square root of the rational function. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = t^2 - 2 + 1/t^2; f.sqrt() - (t^2 - 1)/t - sage: f = t^2; f.sqrt(all=True) - [t, -t] - - TESTS:: - - sage: K(4/9).sqrt() - 2/3 - sage: K(0).sqrt(all=True) - [0] - """ - if all: - return [self._parent(r) for r in self._x.sqrt(all=True)] - else: - return self._parent(self._x.sqrt()) - - cpdef bint is_nth_power(self, n): - r""" - Return whether this element is an ``n``-th power in the rational - function field. - - INPUT: - - - ``n`` -- an integer - - OUTPUT: - - Returns ``True`` if there is an element `a` in the function field such - that this element equals `a^n`. - - ALGORITHM: - - If ``n`` is a power of the characteristic of the field and the constant - base field is perfect, then this uses the algorithm described in Lemma - 3 of [GiTr1996]_. - - .. SEEALSO:: - - :meth:`nth_root` - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: f = (x+1)/(x-1) # optional - sage.libs.pari - sage: f.is_nth_power(1) # optional - sage.libs.pari - True - sage: f.is_nth_power(3) # optional - sage.libs.pari - False - sage: (f^3).is_nth_power(3) # optional - sage.libs.pari - True - sage: (f^9).is_nth_power(-9) # optional - sage.libs.pari - True - """ - if n == 1: - return True - if n < 0: - return (~self).is_nth_power(-n) - - p = self._parent.characteristic() - if n == p: - return self._parent.derivation()(self).is_zero() - if p.divides(n): - return self.is_nth_power(p) and self.nth_root(p).is_nth_power(n//p) - if n == 2: - return self.is_square() - - raise NotImplementedError("is_nth_power() not implemented for the given n") - - cpdef FunctionFieldElement nth_root(self, n): - r""" - Return an ``n``-th root of this element in the function field. - - INPUT: - - - ``n`` -- an integer - - OUTPUT: - - Returns an element ``a`` in the rational function field such that this - element equals `a^n`. Raises an error if no such element exists. - - ALGORITHM: - - If ``n`` is a power of the characteristic of the field and the constant - base field is perfect, then this uses the algorithm described in - Corollary 3 of [GiTr1996]_. - - .. SEEALSO:: - - :meth:`is_nth_power` - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: f = (x+1)/(x+2) # optional - sage.libs.pari - sage: f.nth_root(1) # optional - sage.libs.pari - (x + 1)/(x + 2) - sage: f.nth_root(3) # optional - sage.libs.pari - Traceback (most recent call last): - ... - ValueError: element is not an n-th power - sage: (f^3).nth_root(3) # optional - sage.libs.pari - (x + 1)/(x + 2) - sage: (f^9).nth_root(-9) # optional - sage.libs.pari - (x + 2)/(x + 1) - """ - if n == 0: - if not self.is_one(): - raise ValueError("element is not a 0-th power") - return self - if n == 1: - return self - if n < 0: - return (~self).nth_root(-n) - p = self._parent.characteristic() - if p.divides(n): - if not self.is_nth_power(p): - raise ValueError("element is not an n-th power") - return self._parent(self.numerator().nth_root(p) / self.denominator().nth_root(p)).nth_root(n//p) - if n == 2: - return self.sqrt() - - raise NotImplementedError("nth_root() not implemented for {}".format(n)) - - def factor(self): - """ - Factor the rational function. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = (t+1) / (t^2 - 1/3) - sage: f.factor() # optional - sage.libs.pari - (t + 1) * (t^2 - 1/3)^-1 - sage: (7*f).factor() # optional - sage.libs.pari - (7) * (t + 1) * (t^2 - 1/3)^-1 - sage: ((7*f).factor()).unit() # optional - sage.libs.pari - 7 - sage: (f^3).factor() # optional - sage.libs.pari - (t + 1)^3 * (t^2 - 1/3)^-3 - """ - P = self.parent() - F = self._x.factor() - from sage.structure.factorization import Factorization - return Factorization([(P(a),e) for a,e in F], unit=F.unit()) - - def inverse_mod(self, I): - """ - Return an inverse of the element modulo the integral ideal `I`, if `I` - and the element together generate the unit ideal. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order(); I = O.ideal(x^2+1) - sage: t = O(x+1).inverse_mod(I); t - -1/2*x + 1/2 - sage: (t*(x+1) - 1) in I - True - - """ - assert len(I.gens()) == 1 - f = I.gens()[0]._x - assert f.denominator() == 1 - assert self._x.denominator() == 1 - return self.parent()(self._x.numerator().inverse_mod(f.numerator())) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 80bdcf96c42..169d7642f4c 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -210,6 +210,7 @@ - Brent Baccala (2019-12-20): added function fields over number fields and QQbar """ + # **************************************************************************** # Copyright (C) 2010 William Stein # Copyright (C) 2010 Robert Bradshaw @@ -221,23 +222,14 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.arith.functions import lcm + from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import LazyImport -from sage.rings.integer import Integer from sage.rings.ring import Field -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.qqbar_decorators import handle_AA_and_QQbar - from sage.categories.homset import Hom from sage.categories.function_fields import FunctionFields from sage.structure.category_object import CategoryObject -from .element import ( - FunctionFieldElement, - FunctionFieldElement_rational, - FunctionFieldElement_polymod) - def is_FunctionField(x): """ @@ -766,6 +758,7 @@ def _convert_map_from_(self, R): sage: K(L(x)) # indirect doctest # optional - sage.libs.singular x """ + from .function_field_polymod import FunctionField_polymod if isinstance(R, FunctionField_polymod): base_conversion = self.convert_map_from(R.base_field()) if base_conversion is not None: @@ -847,6 +840,8 @@ def rational_function_field(self): sage: M.rational_function_field() # optional - sage.libs.singular Rational function field in x over Rational Field """ + from .function_field_rational import RationalFunctionField + return self if isinstance(self, RationalFunctionField) else self.base_field().rational_function_field() def valuation(self, prime): @@ -962,7 +957,7 @@ def valuation(self, prime): (x)-adic valuation """ - from sage.rings.function_field.function_field_valuation import FunctionFieldValuation + from sage.rings.function_field.valuation import FunctionFieldValuation return FunctionFieldValuation(self, prime) def space_of_differentials(self): @@ -1203,3487 +1198,3 @@ def extension_constant_field(self, k): """ from .extensions import ConstantFieldExtension return ConstantFieldExtension(self, k) - - -class FunctionField_polymod(FunctionField): - """ - Function fields defined by a univariate polynomial, as an extension of the - base field. - - INPUT: - - - ``polynomial`` -- univariate polynomial over a function field - - - ``names`` -- tuple of length 1 or string; variable names - - - ``category`` -- category (default: category of function fields) - - EXAMPLES: - - We make a function field defined by a degree 5 polynomial over the - rational function field over the rational numbers:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular - Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - - We next make a function field over the above nontrivial function - field L:: - - sage: S. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 + y*z + y); M # optional - sage.libs.singular - Function field in z defined by z^2 + y*z + y - sage: 1/z # optional - sage.libs.singular - ((-x/(x^4 + 1))*y^4 + 2*x^2/(x^4 + 1))*z - 1 - sage: z * (1/z) # optional - sage.libs.singular - 1 - - We drill down the tower of function fields:: - - sage: M.base_field() # optional - sage.libs.singular - Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: M.base_field().base_field() # optional - sage.libs.singular - Rational function field in x over Rational Field - sage: M.base_field().base_field().constant_field() # optional - sage.libs.singular - Rational Field - sage: M.constant_base_field() # optional - sage.libs.singular - Rational Field - - .. WARNING:: - - It is not checked if the polynomial used to define the function field is irreducible - Hence it is not guaranteed that this object really is a field! - This is illustrated below. - - :: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(x^2 - y^2) # optional - sage.libs.singular - sage: (y - x)*(y + x) # optional - sage.libs.singular - 0 - sage: 1/(y - x) # optional - sage.libs.singular - 1 - sage: y - x == 0; y + x == 0 # optional - sage.libs.singular - False - False - """ - Element = FunctionFieldElement_polymod - - def __init__(self, polynomial, names, category=None): - """ - Create a function field defined as an extension of another function - field by adjoining a root of a univariate polynomial. - - EXAMPLES: - - We create an extension of a function field:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular - Function field in y defined by y^5 + x*y - x^3 - 3*x - sage: TestSuite(L).run(max_runs=512) # long time (15s) # optional - sage.libs.singular - - We can set the variable name, which doesn't have to be y:: - - sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular - Function field in w defined by w^5 + x*w - x^3 - 3*x - - TESTS: - - Test that :trac:`17033` is fixed:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: M. = K.extension(x^7 - x - t) # optional - sage.libs.singular - sage: M(x) # optional - sage.libs.singular - z - sage: M('z') # optional - sage.libs.singular - z - sage: M('x') # optional - sage.libs.singular - Traceback (most recent call last): - ... - TypeError: unable to evaluate 'x' in Fraction Field of Univariate - Polynomial Ring in t over Rational Field - """ - from sage.rings.polynomial.polynomial_element import Polynomial - if polynomial.parent().ngens()>1 or not isinstance(polynomial, Polynomial): - raise TypeError("polynomial must be univariate a polynomial") - if names is None: - names = (polynomial.variable_name(), ) - elif names != polynomial.variable_name(): - polynomial = polynomial.change_variable_name(names) - if polynomial.degree() <= 0: - raise ValueError("polynomial must have positive degree") - base_field = polynomial.base_ring() - if not isinstance(base_field, FunctionField): - raise TypeError("polynomial must be over a FunctionField") - - self._base_field = base_field - self._polynomial = polynomial - - FunctionField.__init__(self, base_field, names=names, - category=FunctionFields().or_subcategory(category)) - - from .place import FunctionFieldPlace_polymod - self._place_class = FunctionFieldPlace_polymod - - self._hash = hash(polynomial) - self._ring = self._polynomial.parent() - - self._populate_coercion_lists_(coerce_list=[base_field, self._ring]) - self._gen = self(self._ring.gen()) - - def __hash__(self): - """ - Return hash of the function field. - - The hash value is equal to the hash of the defining polynomial. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular - sage: hash(L) == hash(L.polynomial()) # optional - sage.libs.singular - True - """ - return self._hash - - def _element_constructor_(self, x): - r""" - Make ``x`` into an element of the function field, possibly not canonically. - - INPUT: - - - ``x`` -- element - - TESTS:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L._element_constructor_(L.polynomial_ring().gen()) # optional - sage.libs.singular - y - """ - if isinstance(x, FunctionFieldElement): - return self.element_class(self, self._ring(x.element())) - return self.element_class(self, self._ring(x)) - - def gen(self, n=0): - """ - Return the `n`-th generator of the function field. By default, `n` is 0; any other - value of `n` leads to an error. The generator is the class of `y`, if we view - the function field as being presented as `K[y]/(f(y))`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.gen() # optional - sage.libs.singular - y - sage: L.gen(1) # optional - sage.libs.singular - Traceback (most recent call last): - ... - IndexError: there is only one generator - """ - if n != 0: - raise IndexError("there is only one generator") - return self._gen - - def ngens(self): - """ - Return the number of generators of the function field over its base - field. This is by definition 1. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.ngens() # optional - sage.libs.singular - 1 - """ - return 1 - - def _to_base_field(self, f): - r""" - Return ``f`` as an element of the :meth:`base_field`. - - INPUT: - - - ``f`` -- element of the function field which lies in the base - field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L._to_base_field(L(x)) # optional - sage.libs.singular - x - sage: L._to_base_field(y) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: y is not an element of the base field - - TESTS: - - Verify that :trac:`21872` has been resolved:: - - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - - sage: M(1) in QQ # optional - sage.libs.singular - True - sage: M(y) in L # optional - sage.libs.singular - True - sage: M(x) in K # optional - sage.libs.singular - True - sage: z in K # optional - sage.libs.singular - False - """ - K = self.base_field() - if f.element().is_constant(): - return K(f.element()) - raise ValueError("%r is not an element of the base field"%(f,)) - - def _to_constant_base_field(self, f): - """ - Return ``f`` as an element of the :meth:`constant_base_field`. - - INPUT: - - - ``f`` -- element of the rational function field which is a - constant - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L._to_constant_base_field(L(1)) # optional - sage.libs.singular - 1 - sage: L._to_constant_base_field(y) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: y is not an element of the base field - - TESTS: - - Verify that :trac:`21872` has been resolved:: - - sage: L(1) in QQ # optional - sage.libs.singular - True - sage: y in QQ # optional - sage.libs.singular - False - """ - return self.base_field()._to_constant_base_field(self._to_base_field(f)) - - def monic_integral_model(self, names=None): - """ - Return a function field isomorphic to this field but which is an - extension of a rational function field with defining polynomial that is - monic and integral over the constant base field. - - INPUT: - - - ``names`` -- a string or a tuple of up to two strings (default: - ``None``), the name of the generator of the field, and the name of - the generator of the underlying rational function field (if a tuple); - if not given, then the names are chosen automatically. - - OUTPUT: - - A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an - isomorphism from ``F`` to this field, and ``t`` is the inverse of - ``f``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular - Function field in y defined by x^2*y^5 - 1/x - sage: A, from_A, to_A = L.monic_integral_model('z') # optional - sage.libs.singular - sage: A # optional - sage.libs.singular - Function field in z defined by z^5 - x^12 - sage: from_A # optional - sage.libs.singular - Function Field morphism: - From: Function field in z defined by z^5 - x^12 - To: Function field in y defined by x^2*y^5 - 1/x - Defn: z |--> x^3*y - x |--> x - sage: to_A # optional - sage.libs.singular - Function Field morphism: - From: Function field in y defined by x^2*y^5 - 1/x - To: Function field in z defined by z^5 - x^12 - Defn: y |--> 1/x^3*z - x |--> x - sage: to_A(y) # optional - sage.libs.singular - 1/x^3*z - sage: from_A(to_A(y)) # optional - sage.libs.singular - y - sage: from_A(to_A(1/y)) # optional - sage.libs.singular - x^3*y^4 - sage: from_A(to_A(1/y)) == 1/y # optional - sage.libs.singular - True - - This also works for towers of function fields:: - - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2*y - 1/x) # optional - sage.libs.singular - sage: M.monic_integral_model() # optional - sage.libs.singular - (Function field in z_ defined by z_^10 - x^18, - Function Field morphism: - From: Function field in z_ defined by z_^10 - x^18 - To: Function field in z defined by y*z^2 - 1/x - Defn: z_ |--> x^2*z - x |--> x, Function Field morphism: - From: Function field in z defined by y*z^2 - 1/x - To: Function field in z_ defined by z_^10 - x^18 - Defn: z |--> 1/x^2*z_ - y |--> 1/x^15*z_^8 - x |--> x) - - TESTS: - - If the field is already a monic integral extension, then it is returned - unchanged:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L.monic_integral_model() # optional - sage.libs.singular - (Function field in y defined by y^2 - x, - Function Field endomorphism of Function field in y defined by y^2 - x - Defn: y |--> y - x |--> x, Function Field endomorphism of Function field in y defined by y^2 - x - Defn: y |--> y - x |--> x) - - unless ``names`` does not match with the current names:: - - sage: L.monic_integral_model(names=('yy','xx')) # optional - sage.libs.singular - (Function field in yy defined by yy^2 - xx, - Function Field morphism: - From: Function field in yy defined by yy^2 - xx - To: Function field in y defined by y^2 - x - Defn: yy |--> y - xx |--> x, Function Field morphism: - From: Function field in y defined by y^2 - x - To: Function field in yy defined by yy^2 - xx - Defn: y |--> yy - x |--> xx) - - """ - if names: - if not isinstance(names, tuple): - names = (names,) - if len(names) > 2: - raise ValueError("names must contain at most 2 entries") - - if self.base_field() is not self.rational_function_field(): - L,from_L,to_L = self.simple_model() - ret,ret_to_L,L_to_ret = L.monic_integral_model(names) - from_ret = ret.hom( [from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))] ) - to_ret = self.hom( [L_to_ret(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())] ) - return ret, from_ret, to_ret - else: - if self.polynomial().is_monic() and all(c.denominator().is_one() for c in self.polynomial()): - # self is already monic and integral - if names is None or names == (): - names = (self.variable_name(),) - return self.change_variable_name(names) - else: - if not names: - names = (self.variable_name()+"_",) - if len(names) == 1: - names = (names[0], self.rational_function_field().variable_name()) - - g, d = self._make_monic_integral(self.polynomial()) - K,from_K,to_K = self.base_field().change_variable_name(names[1]) - g = g.map_coefficients(to_K) - ret = K.extension(g, names=names[0]) - from_ret = ret.hom([self.gen() * d, self.base_field().gen()]) - to_ret = self.hom([ret.gen() / d, ret.base_field().gen()]) - return ret, from_ret, to_ret - - def _make_monic_integral(self, f): - """ - Return a monic integral polynomial `g` and an element `d` of the base - field such that `g(y*d)=0` where `y` is a root of `f`. - - INPUT: - - - ``f`` -- polynomial - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x) # optional - sage.libs.singular - sage: g, d = L._make_monic_integral(L.polynomial()); g,d # optional - sage.libs.singular - (y^5 - x^12, x^3) - sage: (y*d).is_integral() # optional - sage.libs.singular - True - sage: g.is_monic() # optional - sage.libs.singular - True - sage: g(y*d) # optional - sage.libs.singular - 0 - """ - R = f.base_ring() - if not isinstance(R, RationalFunctionField): - raise NotImplementedError - - # make f monic - n = f.degree() - c = f.leading_coefficient() - if c != 1: - f = f / c - - # find lcm of denominators - # would be good to replace this by minimal... - d = lcm([b.denominator() for b in f.list() if b]) - if d != 1: - x = f.parent().gen() - g = (d**n) * f(x/d) - else: - g = f - return g, d - - def constant_field(self): - """ - Return the algebraic closure of the constant field of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^5 - x) # optional - sage.libs.pari - sage: L.constant_field() # optional - sage.libs.pari - Traceback (most recent call last): - ... - NotImplementedError - """ - raise NotImplementedError - - def constant_base_field(self): - """ - Return the base constant field of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular - Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.constant_base_field() # optional - sage.libs.singular - Rational Field - sage: S. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.constant_base_field() # optional - sage.libs.singular - Rational Field - """ - return self.base_field().constant_base_field() - - @cached_method(key=lambda self, base: self.base_field() if base is None else base) - def degree(self, base=None): - """ - Return the degree of the function field over the function field ``base``. - - INPUT: - - - ``base`` -- a function field (default: ``None``), a function field - from which this field has been constructed as a finite extension. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular - Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.degree() # optional - sage.libs.singular - 5 - sage: L.degree(L) # optional - sage.libs.singular - 1 - - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.degree(L) # optional - sage.libs.singular - 2 - sage: M.degree(K) # optional - sage.libs.singular - 10 - - TESTS:: - - sage: L.degree(M) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: base must be the rational function field itself - - """ - if base is None: - base = self.base_field() - if base is self: - from sage.rings.integer_ring import ZZ - return ZZ(1) - return self._polynomial.degree() * self.base_field().degree(base) - - def _repr_(self): - """ - Return the string representation of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L._repr_() # optional - sage.libs.singular - 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' - """ - return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial) - - def base_field(self): - """ - Return the base field of the function field. This function field is - presented as `L = K[y]/(f(y))`, and the base field is by definition the - field `K`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.base_field() # optional - sage.libs.singular - Rational function field in x over Rational Field - """ - return self._base_field - - def random_element(self, *args, **kwds): - """ - Create a random element of the function field. Parameters are passed - onto the random_element method of the base_field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x)) # optional - sage.libs.singular - sage: L.random_element() # random # optional - sage.libs.singular - ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y - + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95) - """ - return self(self._ring.random_element(degree=self.degree(), *args, **kwds)) - - def polynomial(self): - """ - Return the univariate polynomial that defines the function field, that - is, the polynomial `f(y)` so that the function field is of the form - `K[y]/(f(y))`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.polynomial() # optional - sage.libs.singular - y^5 - 2*x*y + (-x^4 - 1)/x - """ - return self._polynomial - - def is_separable(self, base=None): - r""" - Return whether this is a separable extension of ``base``. - - INPUT: - - - ``base`` -- a function field from which this field has been created - as an extension or ``None`` (default: ``None``); if ``None``, then - return whether this is a separable extension over its base field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari - False - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari - sage: M.is_separable() # optional - sage.libs.pari - True - sage: M.is_separable(K) # optional - sage.libs.pari - False - - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari - True - - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - 1) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari - False - - """ - if base is None: - base = self.base_field() - for k in self._intermediate_fields(base)[:-1]: - f = k.polynomial() - g = f.derivative() - if f.gcd(g).degree() != 0: - return False - return True - - def polynomial_ring(self): - """ - Return the polynomial ring used to represent elements of the - function field. If we view the function field as being presented - as `K[y]/(f(y))`, then this function returns the ring `K[y]`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.polynomial_ring() # optional - sage.libs.singular - Univariate Polynomial Ring in y over Rational function field in x over Rational Field - """ - return self._ring - - @cached_method(key=lambda self, base, basis, map: (self.base_field() if base is None else base, basis, map)) - def free_module(self, base=None, basis=None, map=True): - """ - Return a vector space and isomorphisms from the field to and from the - vector space. - - This function allows us to identify the elements of this field with - elements of a vector space over the base field, which is useful for - representation and arithmetic with orders, ideals, etc. - - INPUT: - - - ``base`` -- a function field (default: ``None``), the returned vector - space is over this subfield `R`, which defaults to the base field of this - function field. - - - ``basis`` -- a basis for this field over the base. - - - ``maps`` -- boolean (default ``True``), whether to return - `R`-linear maps to and from `V`. - - OUTPUT: - - - a vector space over the base function field - - - an isomorphism from the vector space to the field (if requested) - - - an isomorphism from the field to the vector space (if requested) - - EXAMPLES: - - We define a function field:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular - Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - - We get the vector spaces, and maps back and forth:: - - sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular sage.modules - sage: V # optional - sage.libs.singular sage.modules - Vector space of dimension 5 over Rational function field in x over Rational Field - sage: from_V # optional - sage.libs.singular sage.modules - Isomorphism: - From: Vector space of dimension 5 over Rational function field in x over Rational Field - To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: to_V # optional - sage.libs.singular sage.modules - Isomorphism: - From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - To: Vector space of dimension 5 over Rational function field in x over Rational Field - - We convert an element of the vector space back to the function field:: - - sage: from_V(V.1) # optional - sage.libs.singular sage.modules - y - - We define an interesting element of the function field:: - - sage: a = 1/L.0; a # optional - sage.libs.singular sage.modules - (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1) - - We convert it to the vector space, and get a vector over the base field:: - - sage: to_V(a) # optional - sage.libs.singular sage.modules - (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1)) - - We convert to and back, and get the same element:: - - sage: from_V(to_V(a)) == a # optional - sage.libs.singular sage.modules - True - - In the other direction:: - - sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular sage.modules - sage: to_V(from_V(v)) == v # optional - sage.libs.singular sage.modules - True - - And we show how it works over an extension of an extension field:: - - sage: R2. = L[]; M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.free_module() # optional - sage.libs.singular sage.modules - (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism: - From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - To: Function field in z defined by z^2 - y, Isomorphism: - From: Function field in z defined by z^2 - y - To: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x) - - We can also get the vector space of ``M`` over ``K``:: - - sage: M.free_module(K) # optional - sage.libs.singular sage.modules - (Vector space of dimension 10 over Rational function field in x over Rational Field, Isomorphism: - From: Vector space of dimension 10 over Rational function field in x over Rational Field - To: Function field in z defined by z^2 - y, Isomorphism: - From: Function field in z defined by z^2 - y - To: Vector space of dimension 10 over Rational function field in x over Rational Field) - - """ - if basis is not None: - raise NotImplementedError - from .maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace - if base is None: - base = self.base_field() - degree = self.degree(base) - V = base**degree - if not map: - return V - from_V = MapVectorSpaceToFunctionField(V, self) - to_V = MapFunctionFieldToVectorSpace(self, V) - return (V, from_V, to_V) - - def maximal_order(self): - """ - Return the maximal order of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.maximal_order() # optional - sage.libs.singular - Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - """ - from .order import FunctionFieldMaximalOrder_polymod - return FunctionFieldMaximalOrder_polymod(self) - - def maximal_order_infinite(self): - """ - Return the maximal infinite order of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.maximal_order_infinite() # optional - sage.libs.singular - Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari - Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.maximal_order_infinite() # optional - sage.libs.pari - Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - from .order import FunctionFieldMaximalOrderInfinite_polymod - return FunctionFieldMaximalOrderInfinite_polymod(self) - - def different(self): - """ - Return the different of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F.different() # optional - sage.libs.pari - 2*Place (x, (1/(x^3 + x^2 + x))*y^2) - + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) - """ - O = self.maximal_order() - Oinf = self.maximal_order_infinite() - return O.different().divisor() + Oinf.different().divisor() - - def equation_order(self): - """ - Return the equation order of the function field. - - If we view the function field as being presented as `K[y]/(f(y))`, then - the order generated by the class of `y` is returned. If `f` - is not monic, then :meth:`_make_monic_integral` is called, and instead - we get the order generated by some integral multiple of a root of `f`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.basis() # optional - sage.libs.singular - (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4) - - We try an example, in which the defining polynomial is not - monic and is not integral:: - - sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular - sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular - Function field in y defined by x^2*y^5 - 1/x - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.basis() # optional - sage.libs.singular - (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4) - """ - d = self._make_monic_integral(self.polynomial())[1] - return self.order(d*self.gen(), check=False) - - def hom(self, im_gens, base_morphism=None): - """ - Create a homomorphism from the function field to another function field. - - INPUT: - - - ``im_gens`` -- list of images of the generators of the function field - and of successive base rings. - - - ``base_morphism`` -- homomorphism of the base ring, after the - ``im_gens`` are used. Thus if ``im_gens`` has length 2, then - ``base_morphism`` should be a morphism from the base ring of the base - ring of the function field. - - EXAMPLES: - - We create a rational function field, and a quadratic extension of it:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - - We make the field automorphism that sends y to -y:: - - sage: f = L.hom(-y); f # optional - sage.libs.singular - Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 - Defn: y |--> -y - - Evaluation works:: - - sage: f(y*x - 1/x) # optional - sage.libs.singular - -x*y - 1/x - - We try to define an invalid morphism:: - - sage: f = L.hom(y + 1) # optional - sage.libs.singular - Traceback (most recent call last): - ... - ValueError: invalid morphism - - We make a morphism of the base rational function field:: - - sage: phi = K.hom(x + 1); phi # optional - sage.libs.singular - Function Field endomorphism of Rational function field in x over Rational Field - Defn: x |--> x + 1 - sage: phi(x^3 - 3) # optional - sage.libs.singular - x^3 + 3*x^2 + 3*x - 2 - sage: (x+1)^3 - 3 # optional - sage.libs.singular - x^3 + 3*x^2 + 3*x - 2 - - We make a morphism by specifying where the generators and the - base generators go:: - - sage: L.hom([-y, x]) # optional - sage.libs.singular - Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 - Defn: y |--> -y - x |--> x - - You can also specify a morphism on the base:: - - sage: R1. = K[] - sage: L1. = K.extension(q^2 - (x+1)^3 - 1) # optional - sage.libs.singular - sage: L.hom(q, base_morphism=phi) # optional - sage.libs.singular - Function Field morphism: - From: Function field in y defined by y^2 - x^3 - 1 - To: Function field in q defined by q^2 - x^3 - 3*x^2 - 3*x - 2 - Defn: y |--> q - x |--> x + 1 - - We make another extension of a rational function field:: - - sage: K2. = FunctionField(QQ); R2. = K2[] - sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) # optional - sage.libs.singular - - We define a morphism, by giving the images of generators:: - - sage: f = L.hom([4*w, t + 1]); f # optional - sage.libs.singular - Function Field morphism: - From: Function field in y defined by y^2 - x^3 - 1 - To: Function field in w defined by 16*w^2 - t^3 - 3*t^2 - 3*t - 2 - Defn: y |--> 4*w - x |--> t + 1 - - Evaluation works, as expected:: - - sage: f(y+x) # optional - sage.libs.singular - 4*w + t + 1 - sage: f(x*y + x/(x^2+1)) # optional - sage.libs.singular - (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2) - - We make another extension of a rational function field:: - - sage: K3. = FunctionField(QQ); R3. = K3[] - sage: L3. = K3.extension(yy^2 - xx^3 - 1) # optional - sage.libs.singular - - This is the function field L with the generators exchanged. We define a morphism to L:: - - sage: g = L3.hom([x,y]); g # optional - sage.libs.singular - Function Field morphism: - From: Function field in xx defined by -xx^3 + yy^2 - 1 - To: Function field in y defined by y^2 - x^3 - 1 - Defn: xx |--> x - yy |--> y - - """ - if not isinstance(im_gens, (list,tuple)): - im_gens = [im_gens] - if len(im_gens) == 0: - raise ValueError("no images specified") - - if len(im_gens) > 1: - base_morphism = self.base_field().hom(im_gens[1:], base_morphism) - - # the codomain of this morphism is the field containing all the im_gens - codomain = im_gens[0].parent() - if base_morphism is not None: - from sage.categories.pushout import pushout - codomain = pushout(codomain, base_morphism.codomain()) - - from .maps import FunctionFieldMorphism_polymod - return FunctionFieldMorphism_polymod(self.Hom(codomain), im_gens[0], base_morphism) - - @cached_method - def genus(self): - """ - Return the genus of the function field. - - For now, the genus is computed using Singular. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.genus() # optional - sage.libs.singular - 3 - """ - # Unfortunately Singular can not compute the genus with the - # polynomial_ring()._singular_ object because genus method only accepts - # a ring of transcendental degree 2 over a prime field not a ring of - # transcendental degree 1 over a rational function field of one variable - - if (isinstance(self._base_field, RationalFunctionField) and - self._base_field.constant_field().is_prime_field()): - from sage.interfaces.singular import singular - - # making the auxiliary ring which only has polynomials - # with integral coefficients. - tmpAuxRing = PolynomialRing(self._base_field.constant_field(), - str(self._base_field.gen())+','+str(self._ring.gen())) - intMinPoly, d = self._make_monic_integral(self._polynomial) - curveIdeal = tmpAuxRing.ideal(intMinPoly) - - singular.lib('normal.lib') #loading genus method in Singular - return int(curveIdeal._singular_().genus()) - - else: - raise NotImplementedError("computation of genus over non-prime " - "constant fields not implemented yet") - - def _simple_model(self, name='v'): - r""" - Return a finite extension `N/K(x)` isomorphic to the tower of - extensions `M/L/K(x)` with `K` perfect. - - Helper method for :meth:`simple_model`. - - INPUT: - - - ``name`` -- a string, the name of the generator of `N` - - ALGORITHM: - - Since `K` is perfect, the extension `M/K(x)` is simple, i.e., generated - by a single element [BM1940]_. Therefore, there are only finitely many - intermediate fields (Exercise 3.6.7 in [Bo2009]_). - Let `a` be a generator of `M/L` and let `b` be a generator of `L/K(x)`. - For some `i` the field `N_i=K(x)(a+x^ib)` is isomorphic to `M` and so - it is enough to test for all terms of the form `a+x^ib` whether they - generate a field of the right degree. - Indeed, suppose for contradiction that for all `i` we had `N_i\neq M`. - Then `N_i=N_j` for some `i,j`. Thus `(a+x^ib)-(a+x^jb)=b(x^i-x^j)\in - N_j` and so `b\in N_j`. Similarly, - `a+x^ib-x^{i-j}(a+x^jb)=a(1+x^{i-j})\in N_j` and so `a\in N_j`. - Therefore, `N_j=M`. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M._simple_model() # optional - sage.libs.singular - (Function field in v defined by v^4 - x, - Function Field morphism: - From: Function field in v defined by v^4 - x - To: Function field in z defined by z^2 - y - Defn: v |--> z, - Function Field morphism: - From: Function field in z defined by z^2 - y - To: Function field in v defined by v^4 - x - Defn: z |--> v - y |--> v^2) - - Check that this also works for inseparable extensions:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: M._simple_model() # optional - sage.libs.pari - (Function field in v defined by v^4 + x, - Function Field morphism: - From: Function field in v defined by v^4 + x - To: Function field in z defined by z^2 + y - Defn: v |--> z, - Function Field morphism: - From: Function field in z defined by z^2 + y - To: Function field in v defined by v^4 + x - Defn: z |--> v - y |--> v^2) - - An example where the generator of the last extension does not generate - the extension of the rational function field:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - 1) # optional - sage.libs.pari - sage: M._simple_model() # optional - sage.libs.pari - (Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1, - Function Field morphism: - From: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 - To: Function field in z defined by z^3 + 1 - Defn: v |--> z + y, - Function Field morphism: - From: Function field in z defined by z^3 + 1 - To: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 - Defn: z |--> v^4 + x^2 - y |--> v^4 + v + x^2) - - """ - M = self - L = M.base_field() - K = L.base_field() - - assert(isinstance(K, RationalFunctionField)) - assert(K is not L) - assert(L is not M) - - if not K.constant_field().is_perfect(): - raise NotImplementedError("simple_model() only implemented over perfect constant fields") - - x = K.gen() - b = L.gen() - a = M.gen() - - # using a+x^i*b tends to lead to huge powers of x in the minimal - # polynomial of the resulting field; it is better to try terms of - # the form a+i*b first (but in characteristic p>0 there are only - # finitely many of these) - # We systematically try elements of the form a+b*factor*x^exponent - factor = self.constant_base_field().zero() - exponent = 0 - while True: - v = M(a+b*factor*x**exponent) - minpoly = v.matrix(K).minpoly() - if minpoly.degree() == M.degree()*L.degree(): - break - factor += 1 - if factor == 0: - factor = self.constant_base_field().one() - exponent += 1 - - N = K.extension(minpoly, names=(name,)) - - # the morphism N -> M, v |-> v - N_to_M = N.hom(v) - - # the morphism M -> N, b |-> M_b, a |-> M_a - V, V_to_M, M_to_V = M.free_module(K) - V, V_to_N, N_to_V = N.free_module(K) - from sage.matrix.matrix_space import MatrixSpace - MS = MatrixSpace(V.base_field(), V.dimension()) - # the power basis of v over K - B = [M_to_V(v**i) for i in range(V.dimension())] - B = MS(B) - M_b = V_to_N(B.solve_left(M_to_V(b))) - M_a = V_to_N(B.solve_left(M_to_V(a))) - M_to_N = M.hom([M_a,M_b]) - - return N, N_to_M, M_to_N - - @cached_method - def simple_model(self, name=None): - """ - Return a function field isomorphic to this field which is a simple - extension of a rational function field. - - INPUT: - - - ``name`` -- a string (default: ``None``), the name of generator of - the simple extension. If ``None``, then the name of the generator - will be the same as the name of the generator of this function field. - - OUTPUT: - - A triple ``(F,f,t)`` where ``F`` is a field isomorphic to this field, - ``f`` is an isomorphism from ``F`` to this function field and ``t`` is - the inverse of ``f``. - - EXAMPLES: - - A tower of four function fields:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(z^2 - x); R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(u^2 - z); R. = M[] # optional - sage.libs.singular - sage: N. = M.extension(v^2 - u) # optional - sage.libs.singular - - The fields N and M as simple extensions of K:: - - sage: N.simple_model() # optional - sage.libs.singular - (Function field in v defined by v^8 - x, - Function Field morphism: - From: Function field in v defined by v^8 - x - To: Function field in v defined by v^2 - u - Defn: v |--> v, - Function Field morphism: - From: Function field in v defined by v^2 - u - To: Function field in v defined by v^8 - x - Defn: v |--> v - u |--> v^2 - z |--> v^4 - x |--> x) - sage: M.simple_model() # optional - sage.libs.singular - (Function field in u defined by u^4 - x, - Function Field morphism: - From: Function field in u defined by u^4 - x - To: Function field in u defined by u^2 - z - Defn: u |--> u, - Function Field morphism: - From: Function field in u defined by u^2 - z - To: Function field in u defined by u^4 - x - Defn: u |--> u - z |--> u^2 - x |--> x) - - An optional parameter ``name`` can be used to set the name of the - generator of the simple extension:: - - sage: M.simple_model(name='t') # optional - sage.libs.singular - (Function field in t defined by t^4 - x, Function Field morphism: - From: Function field in t defined by t^4 - x - To: Function field in u defined by u^2 - z - Defn: t |--> u, Function Field morphism: - From: Function field in u defined by u^2 - z - To: Function field in t defined by t^4 - x - Defn: u |--> t - z |--> t^2 - x |--> x) - - An example with higher degrees:: - - sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5-x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3-x) # optional - sage.libs.pari - sage: M.simple_model() # optional - sage.libs.pari - (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3, - Function Field morphism: - From: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 - To: Function field in z defined by z^3 + 2*x - Defn: z |--> z + y, - Function Field morphism: - From: Function field in z defined by z^3 + 2*x - To: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 - Defn: z |--> 2/x*z^6 + 2*z^3 + z + 2*x - y |--> 1/x*z^6 + z^3 + x - x |--> x) - - This also works for inseparable extensions:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2-x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2-y) # optional - sage.libs.pari - sage: M.simple_model() # optional - sage.libs.pari - (Function field in z defined by z^4 + x, Function Field morphism: - From: Function field in z defined by z^4 + x - To: Function field in z defined by z^2 + y - Defn: z |--> z, Function Field morphism: - From: Function field in z defined by z^2 + y - To: Function field in z defined by z^4 + x - Defn: z |--> z - y |--> z^2 - x |--> x) - """ - if name is None: - name = self.variable_name() - - if isinstance(self.base_field(), RationalFunctionField): - # the extension is simple already - if name == self.variable_name(): - id = Hom(self,self).identity() - return self, id, id - else: - ret = self.base_field().extension(self.polynomial(), names=(name,)) - f = ret.hom(self.gen()) - t = self.hom(ret.gen()) - return ret, f, t - else: - # recursively collapse the tower of fields - base = self.base_field() - base_, from_base_, to_base_ = base.simple_model() - self_ = base_.extension(self.polynomial().map_coefficients(to_base_), names=(name,)) - gens_in_base_ = [to_base_(k.gen()) - for k in base._intermediate_fields(base.rational_function_field())] - to_self_ = self.hom([self_.gen()]+gens_in_base_) - from_self_ = self_.hom([self.gen(),from_base_(base_.gen())]) - - # now collapse self_/base_/K(x) - ret, ret_to_self_, self__to_ret = self_._simple_model(name) - ret_to_self = ret.hom(from_self_(ret_to_self_(ret.gen()))) - gens_in_ret = [self__to_ret(to_self_(k.gen())) - for k in self._intermediate_fields(self.rational_function_field())] - self_to_ret = self.hom(gens_in_ret) - return ret, ret_to_self, self_to_ret - - @cached_method - def primitive_element(self): - r""" - Return a primitive element over the underlying rational function field. - - If this is a finite extension of a rational function field `K(x)` with - `K` perfect, then this is a simple extension of `K(x)`, i.e., there is - a primitive element `y` which generates this field over `K(x)`. This - method returns such an element `y`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: N. = L.extension(z^2 - x - 1) # optional - sage.libs.singular - sage: N.primitive_element() # optional - sage.libs.singular - u + y - sage: M.primitive_element() # optional - sage.libs.singular - z - sage: L.primitive_element() # optional - sage.libs.singular - y - - This also works for inseparable extensions:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2-x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(Z^2-y) # optional - sage.libs.pari - sage: M.primitive_element() # optional - sage.libs.pari - z - """ - N, f, t = self.simple_model() - return f(N.gen()) - - @cached_method - def separable_model(self, names=None): - r""" - Return a function field isomorphic to this field which is a separable - extension of a rational function field. - - INPUT: - - - ``names`` -- a tuple of two strings or ``None`` (default: ``None``); - the second entry will be used as the variable name of the rational - function field, the first entry will be used as the variable name of - its separable extension. If ``None``, then the variable names will be - chosen automatically. - - OUTPUT: - - A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an - isomorphism from ``F`` to this function field, and ``t`` is the inverse - of ``f``. - - ALGORITHM: - - Suppose that the constant base field is perfect. If this is a monic - integral inseparable extension of a rational function field, then the - defining polynomial is separable if we swap the variables (Proposition - 4.8 in Chapter VIII of [Lan2002]_.) - The algorithm reduces to this case with :meth:`monic_integral_model`. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.pari - sage: L.separable_model(('t','w')) # optional - sage.libs.pari - (Function field in t defined by t^3 + w^2, - Function Field morphism: - From: Function field in t defined by t^3 + w^2 - To: Function field in y defined by y^2 + x^3 - Defn: t |--> x - w |--> y, - Function Field morphism: - From: Function field in y defined by y^2 + x^3 - To: Function field in t defined by t^3 + w^2 - Defn: y |--> w - x |--> t) - - This also works for non-integral polynomials:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2/x - x^2) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari - (Function field in y_ defined by y_^3 + x_^2, - Function Field morphism: - From: Function field in y_ defined by y_^3 + x_^2 - To: Function field in y defined by 1/x*y^2 + x^2 - Defn: y_ |--> x - x_ |--> y, - Function Field morphism: - From: Function field in y defined by 1/x*y^2 + x^2 - To: Function field in y_ defined by y_^3 + x_^2 - Defn: y |--> x_ - x |--> y_) - - If the base field is not perfect this is only implemented in trivial cases:: - - sage: k. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: k.is_perfect() # optional - sage.libs.pari - False - sage: K. = FunctionField(k) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - t) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari - (Function field in y defined by y^3 + t, - Function Field endomorphism of Function field in y defined by y^3 + t - Defn: y |--> y - x |--> x, - Function Field endomorphism of Function field in y defined by y^3 + t - Defn: y |--> y - x |--> x) - - Some other cases for which a separable model could be constructed are - not supported yet:: - - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - t) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari - Traceback (most recent call last): - ... - NotImplementedError: constructing a separable model is only implemented for function fields over a perfect constant base field - - TESTS: - - Check that this also works in characteristic zero:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.singular - sage: L.separable_model() # optional - sage.libs.singular - (Function field in y defined by y^2 - x^3, - Function Field endomorphism of Function field in y defined by y^2 - x^3 - Defn: y |--> y - x |--> x, - Function Field endomorphism of Function field in y defined by y^2 - x^3 - Defn: y |--> y - x |--> x) - - Check that this works for towers of inseparable extensions:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: M.separable_model() # optional - sage.libs.pari - (Function field in z_ defined by z_ + x_^4, - Function Field morphism: - From: Function field in z_ defined by z_ + x_^4 - To: Function field in z defined by z^2 + y - Defn: z_ |--> x - x_ |--> z, - Function Field morphism: - From: Function field in z defined by z^2 + y - To: Function field in z_ defined by z_ + x_^4 - Defn: z |--> x_ - y |--> x_^2 - x |--> x_^4) - - Check that this also works if only the first extension is inseparable:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari - sage: M.separable_model() # optional - sage.libs.pari - (Function field in z_ defined by z_ + x_^6, Function Field morphism: - From: Function field in z_ defined by z_ + x_^6 - To: Function field in z defined by z^3 + y - Defn: z_ |--> x - x_ |--> z, Function Field morphism: - From: Function field in z defined by z^3 + y - To: Function field in z_ defined by z_ + x_^6 - Defn: z |--> x_ - y |--> x_^3 - x |--> x_^6) - - """ - if names is None: - pass - elif not isinstance(names, tuple): - raise TypeError("names must be a tuple consisting of two strings") - elif len(names) != 2: - raise ValueError("must provide exactly two variable names") - - if self.base_ring() is not self.rational_function_field(): - L, from_L, to_L = self.simple_model() - K, from_K, to_K = L.separable_model(names=names) - f = K.hom([from_L(from_K(K.gen())), from_L(from_K(K.base_field().gen()))]) - t = self.hom([to_K(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())]) - return K, f, t - - if self.polynomial().gcd(self.polynomial().derivative()).is_one(): - # the model is already separable - if names is None: - names = self.variable_name(), self.base_field().variable_name() - return self.change_variable_name(names) - - if not self.constant_base_field().is_perfect(): - raise NotImplementedError("constructing a separable model is only implemented for function fields over a perfect constant base field") - - if names is None: - names = (self.variable_name()+"_", self.rational_function_field().variable_name()+"_") - - L, from_L, to_L = self.monic_integral_model() - - if L.polynomial().gcd(L.polynomial().derivative()).is_one(): - # L is separable - ret, ret_to_L, L_to_ret = L.change_variable_name(names) - f = ret.hom([from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))]) - t = self.hom([L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))]) - return ret, f, t - else: - # otherwise, the polynomial of L must be separable in the other variable - from .constructor import FunctionField - K = FunctionField(self.constant_base_field(), names=(names[1],)) - # construct a field isomorphic to L on top of K - - # turn the minpoly of K into a bivariate polynomial - if names[0] == names[1]: - raise ValueError("names of generators must be distinct") - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self.constant_base_field(), names=names) - S = R.remove_var(names[1]) - f = R( L.polynomial().change_variable_name(names[1]).map_coefficients( - lambda c:c.numerator().change_variable_name(names[0]), S)) - f = f.polynomial(R.gen(0)).change_ring(K) - f /= f.leading_coefficient() - # f must be separable in the other variable (otherwise it would factor) - assert f.gcd(f.derivative()).is_one() - - ret = K.extension(f, names=(names[0],)) - # isomorphisms between L and ret are given by swapping generators - ret_to_L = ret.hom( [L(L.base_field().gen()), L.gen()] ) - L_to_ret = L.hom( [ret(K.gen()), ret.gen()] ) - # compose with from_L and to_L to get the desired isomorphisms between self and ret - f = ret.hom( [from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))] ) - t = self.hom( [L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))] ) - return ret, f, t - - def change_variable_name(self, name): - r""" - Return a field isomorphic to this field with variable(s) ``name``. - - INPUT: - - - ``name`` -- a string or a tuple consisting of a strings, the names of - the new variables starting with a generator of this field and going - down to the rational function field. - - OUTPUT: - - A triple ``F,f,t`` where ``F`` is a function field, ``f`` is an - isomorphism from ``F`` to this field, and ``t`` is the inverse of - ``f``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - - sage: M.change_variable_name('zz') # optional - sage.libs.singular - (Function field in zz defined by zz^2 - y, - Function Field morphism: - From: Function field in zz defined by zz^2 - y - To: Function field in z defined by z^2 - y - Defn: zz |--> z - y |--> y - x |--> x, - Function Field morphism: - From: Function field in z defined by z^2 - y - To: Function field in zz defined by zz^2 - y - Defn: z |--> zz - y |--> y - x |--> x) - sage: M.change_variable_name(('zz','yy')) # optional - sage.libs.singular - (Function field in zz defined by zz^2 - yy, Function Field morphism: - From: Function field in zz defined by zz^2 - yy - To: Function field in z defined by z^2 - y - Defn: zz |--> z - yy |--> y - x |--> x, Function Field morphism: - From: Function field in z defined by z^2 - y - To: Function field in zz defined by zz^2 - yy - Defn: z |--> zz - y |--> yy - x |--> x) - sage: M.change_variable_name(('zz','yy','xx')) # optional - sage.libs.singular - (Function field in zz defined by zz^2 - yy, - Function Field morphism: - From: Function field in zz defined by zz^2 - yy - To: Function field in z defined by z^2 - y - Defn: zz |--> z - yy |--> y - xx |--> x, - Function Field morphism: - From: Function field in z defined by z^2 - y - To: Function field in zz defined by zz^2 - yy - Defn: z |--> zz - y |--> yy - x |--> xx) - - """ - if not isinstance(name, tuple): - name = (name,) - if len(name) == 0: - raise ValueError("name must contain at least one string") - elif len(name) == 1: - base = self.base_field() - from_base = to_base = Hom(base,base).identity() - else: - base, from_base, to_base = self.base_field().change_variable_name(name[1:]) - - ret = base.extension(self.polynomial().map_coefficients(to_base), names=(name[0],)) - f = ret.hom( [k.gen() for k in self._intermediate_fields(self.rational_function_field())] ) - t = self.hom( [k.gen() for k in ret._intermediate_fields(ret.rational_function_field())] ) - return ret, f, t - - -class FunctionField_simple(FunctionField_polymod): - """ - Function fields defined by irreducible and separable polynomials - over rational function fields. - """ - @cached_method - def _inversion_isomorphism(self): - r""" - Return an inverted function field isomorphic to ``self`` and isomorphisms - between them. - - An *inverted* function field `M` is an extension of the base rational - function field `k(x)` of ``self``, and isomorphic to ``self`` by an - isomorphism sending `x` to `1/x`, which we call an *inversion* - isomorphism. Also the defining polynomial of the function field `M` is - required to be monic and integral. - - The inversion isomorphism is for internal use to reposition infinite - places to finite places. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F._inversion_isomorphism() # optional - sage.libs.pari - (Function field in s defined by s^3 + x^16 + x^14 + x^12, Composite map: - From: Function field in s defined by s^3 + x^16 + x^14 + x^12 - To: Function field in y defined by y^3 + x^6 + x^4 + x^2 - Defn: Function Field morphism: - From: Function field in s defined by s^3 + x^16 + x^14 + x^12 - To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 - Defn: s |--> x^6*T - x |--> x - then - Function Field morphism: - From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 - To: Function field in y defined by y^3 + x^6 + x^4 + x^2 - Defn: T |--> y - x |--> 1/x, Composite map: - From: Function field in y defined by y^3 + x^6 + x^4 + x^2 - To: Function field in s defined by s^3 + x^16 + x^14 + x^12 - Defn: Function Field morphism: - From: Function field in y defined by y^3 + x^6 + x^4 + x^2 - To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 - Defn: y |--> T - x |--> 1/x - then - Function Field morphism: - From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 - To: Function field in s defined by s^3 + x^16 + x^14 + x^12 - Defn: T |--> 1/x^6*s - x |--> x) - """ - K = self.base_field() - R = PolynomialRing(K,'T') - x = K.gen() - xinv = 1/x - - h = K.hom(xinv) - F_poly = R([h(c) for c in self.polynomial().list()]) - F = K.extension(F_poly) - - self2F = self.hom([F.gen(),xinv]) - F2self = F.hom([self.gen(),xinv]) - - M, M2F, F2M = F.monic_integral_model('s') - - return M, F2self*M2F, F2M*self2F - - def places_above(self, p): - """ - Return places lying above ``p``. - - INPUT: - - - ``p`` -- place of the base rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: all(q.place_below() == p # optional - sage.libs.pari - ....: for p in K.places() for q in F.places_above(p)) - True - - sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = K.maximal_order() # optional - sage.libs.singular - sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] # optional - sage.libs.singular - sage: all(q.place_below() == p # optional - sage.libs.singular - ....: for p in pls for q in F.places_above(p)) - True - - sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field - sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular sage.rings.number_field - ....: for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular sage.rings.number_field - ....: for p in pls for q in F.places_above(p)) - True - """ - R = self.base_field() - - if p not in R.place_set(): - raise TypeError("not a place of the base rational function field") - - if p.is_infinite_place(): - dec = self.maximal_order_infinite().decomposition() - else: - dec = self.maximal_order().decomposition(p.prime_ideal()) - - return tuple([q.place() for q, deg, exp in dec]) - - def constant_field(self): - """ - Return the algebraic closure of the base constant field in the function - field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari - sage: L.constant_field() # optional - sage.libs.pari - Finite Field of size 3 - """ - return self.exact_constant_field()[0] - - def exact_constant_field(self, name='t'): - """ - Return the exact constant field and its embedding into the function field. - - INPUT: - - - ``name`` -- name (default: `t`) of the generator of the exact constant field - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible # optional - sage.libs.pari - sage: L. = K.extension(f) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari - 0 - sage: L.exact_constant_field() # optional - sage.libs.pari - (Finite Field in t of size 3^2, Ring morphism: - From: Finite Field in t of size 3^2 - To: Function field in y defined by y^2 + 2*x*y + x^2 + 1 - Defn: t |--> y + x) - sage: (y+x).divisor() # optional - sage.libs.pari - 0 - """ - # A basis of the full constant field is obtained from - # computing a Riemann-Roch basis of zero divisor. - basis = self.divisor_group().zero().basis_function_space() - - dim = len(basis) - - for e in basis: - _min_poly = e.minimal_polynomial(name) - if _min_poly.degree() == dim: - break - k = self.constant_base_field() - R = k[name] - min_poly = R([k(c) for c in _min_poly.list()]) - - k_ext = k.extension(min_poly, name) - - if k_ext.is_prime_field(): - # The cover of the quotient ring k_ext is the integer ring - # whose generator is 1. This is different from the generator - # of k_ext. - embedding = k_ext.hom([self(1)], self) - else: - embedding = k_ext.hom([e], self) - - return k_ext, embedding - - def genus(self): - """ - Return the genus of the function field. - - EXAMPLES:: - - sage: F. = GF(16) # optional - sage.libs.pari - sage: K. = FunctionField(F); K # optional - sage.libs.pari - Rational function field in x over Finite Field in a of size 2^4 - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari - 6 - - The genus is computed by the Hurwitz genus formula. - """ - k, _ = self.exact_constant_field() - different_degree = self.different().degree() # must be even - return Integer(different_degree // 2 - self.degree() / k.degree()) + 1 - - def residue_field(self, place, name=None): - """ - Return the residue field associated with the place along with the maps - from and to the residue field. - - INPUT: - - - ``place`` -- place of the function field - - - ``name`` -- string; name of the generator of the residue field - - The domain of the map to the residue field is the discrete valuation - ring associated with the place. - - The discrete valuation ring is defined as the ring of all elements of - the function field with nonnegative valuation at the place. The maximal - ideal is the set of elements of positive valuation. The residue field - is then the quotient of the discrete valuation ring by its maximal - ideal. - - If an element not in the valuation ring is applied to the map, an - exception ``TypeError`` is raised. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: R, fr_R, to_R = L.residue_field(p) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari - Finite Field of size 2 - sage: f = 1 + y # optional - sage.libs.pari - sage: f.valuation(p) # optional - sage.libs.pari - -1 - sage: to_R(f) # optional - sage.libs.pari - Traceback (most recent call last): - ... - TypeError: ... - sage: (1+1/f).valuation(p) # optional - sage.libs.pari - 0 - sage: to_R(1 + 1/f) # optional - sage.libs.pari - 1 - sage: [fr_R(e) for e in R] # optional - sage.libs.pari - [0, 1] - """ - return place.residue_field(name=name) - - -class FunctionField_char_zero(FunctionField_simple): - """ - Function fields of characteristic zero. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular - sage: L # optional - sage.libs.singular - Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) - sage: L.characteristic() # optional - sage.libs.singular - 0 - """ - @cached_method - def higher_derivation(self): - """ - Return the higher derivation (also called the Hasse-Schmidt derivation) - for the function field. - - The higher derivation of the function field is uniquely determined with - respect to the separating element `x` of the base rational function - field `k(x)`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular - sage: L.higher_derivation() # optional - sage.libs.singular sage.modules - Higher derivation map: - From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) - To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) - """ - from .derivations import FunctionFieldHigherDerivation_char_zero - return FunctionFieldHigherDerivation_char_zero(self) - - -class FunctionField_global(FunctionField_simple): - """ - Global function fields. - - INPUT: - - - ``polynomial`` -- monic irreducible and separable polynomial - - - ``names`` -- name of the generator of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L # optional - sage.libs.pari - Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) - - The defining equation needs not be monic:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension((1 - x)*Y^7 - x^3) # optional - sage.libs.pari - sage: L.gaps() # long time (6s) # optional - sage.libs.pari - [1, 2, 3] - - or may define a trivial extension:: - - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y-1) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari - 0 - """ - _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') - - def __init__(self, polynomial, names): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: TestSuite(L).run() # long time (7s) # optional - sage.libs.pari - """ - FunctionField_polymod.__init__(self, polynomial, names) - - def maximal_order(self): - """ - Return the maximal order of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari - (1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y) - """ - from .order import FunctionFieldMaximalOrder_global - return FunctionFieldMaximalOrder_global(self) - - @cached_method - def higher_derivation(self): - """ - Return the higher derivation (also called the Hasse-Schmidt derivation) - for the function field. - - The higher derivation of the function field is uniquely determined with - respect to the separating element `x` of the base rational function - field `k(x)`. - - EXAMPLES:: - - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.higher_derivation() # optional - sage.libs.pari sage.modules - Higher derivation map: - From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) - To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) - """ - from .derivations import FunctionFieldHigherDerivation_global - return FunctionFieldHigherDerivation_global(self) - - def get_place(self, degree): - """ - Return a place of ``degree``. - - INPUT: - - - ``degree`` -- a positive integer - - OUTPUT: a place of ``degree`` if any exists; otherwise ``None`` - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(Y^4 + Y - x^5) # optional - sage.libs.pari - sage: L.get_place(1) # optional - sage.libs.pari - Place (x, y) - sage: L.get_place(2) # optional - sage.libs.pari - Place (x, y^2 + y + 1) - sage: L.get_place(3) # optional - sage.libs.pari - Place (x^3 + x^2 + 1, y + x^2 + x) - sage: L.get_place(4) # optional - sage.libs.pari - Place (x + 1, x^5 + 1) - sage: L.get_place(5) # optional - sage.libs.pari - Place (x^5 + x^3 + x^2 + x + 1, y + x^4 + 1) - sage: L.get_place(6) # optional - sage.libs.pari - Place (x^3 + x^2 + 1, y^2 + y + x^2) - sage: L.get_place(7) # optional - sage.libs.pari - Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x) - sage: L.get_place(8) # optional - sage.libs.pari - - """ - for p in self._places_finite(degree): - return p - - for p in self._places_infinite(degree): - return p - - return None - - def places(self, degree=1): - """ - Return a list of the places with ``degree``. - - INPUT: - - - ``degree`` -- positive integer (default: `1`) - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places(1) # optional - sage.libs.pari - [Place (1/x, 1/x^4*y^3), Place (x, y), Place (x, y + 1)] - """ - return self.places_infinite(degree) + self.places_finite(degree) - - def places_finite(self, degree=1): - """ - Return a list of the finite places with ``degree``. - - INPUT: - - - ``degree`` -- positive integer (default: `1`) - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places_finite(1) # optional - sage.libs.pari - [Place (x, y), Place (x, y + 1)] - """ - return list(self._places_finite(degree)) - - def _places_finite(self, degree): - """ - Return a generator of finite places with ``degree``. - - INPUT: - - - ``degree`` -- positive integer - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L._places_finite(1) # optional - sage.libs.pari - - """ - O = self.maximal_order() - K = self.base_field() - - degree = Integer(degree) - - for d in degree.divisors(): - for p in K._places_finite(degree=d): - for prime,_,_ in O.decomposition(p.prime_ideal()): - place = prime.place() - if place.degree() == degree: - yield place - - def places_infinite(self, degree=1): - """ - Return a list of the infinite places with ``degree``. - - INPUT: - - - ``degree`` -- positive integer (default: `1`) - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places_infinite(1) # optional - sage.libs.pari - [Place (1/x, 1/x^4*y^3)] - """ - return list(self._places_infinite(degree)) - - def _places_infinite(self, degree): - """ - Return a generator of *infinite* places with ``degree``. - - INPUT: - - - ``degree`` -- positive integer - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L._places_infinite(1) # optional - sage.libs.pari - - """ - Oinf = self.maximal_order_infinite() - for prime,_,_ in Oinf.decomposition(): - place = prime.place() - if place.degree() == degree: - yield place - - def gaps(self): - """ - Return the gaps of the function field. - - These are the gaps at the ordinary places, that is, places which are - not Weierstrass places. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.gaps() # optional - sage.libs.pari sage.modules - [1, 2, 3] - """ - return self._weierstrass_places()[1] - - def weierstrass_places(self): - """ - Return all Weierstrass places of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules - [Place (1/x, 1/x^3*y^2 + 1/x), - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), - Place (x, y), - Place (x + 1, (x^3 + 1)*y + x + 1), - Place (x^3 + x + 1, y + 1), - Place (x^3 + x + 1, y + x^2), - Place (x^3 + x + 1, y + x^2 + 1), - Place (x^3 + x^2 + 1, y + x), - Place (x^3 + x^2 + 1, y + x^2 + 1), - Place (x^3 + x^2 + 1, y + x^2 + x + 1)] - """ - return self._weierstrass_places()[0].support() - - @cached_method - def _weierstrass_places(self): - """ - Return the Weierstrass places together with the gap sequence for - ordinary places. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari sage.modules - 10 - - This method implements Algorithm 30 in [Hes2002b]_. - """ - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - W = self(self.base_field().gen()).differential().divisor() - basis = W._basis() - - if not basis: - return [], [] - d = len(basis) - - der = self.higher_derivation() - M = matrix([basis]) - e = 1 - gaps = [1] - while M.nrows() < d: - row = vector([der._derive(basis[i], e) for i in range(d)]) - if row not in M.row_space(): - M = matrix(M.rows() + [row]) - gaps.append(e + 1) - e += 1 - - # This is faster than M.determinant(). Note that Mx - # is a matrix over univariate polynomial ring. - Mx = matrix(M.nrows(), [c._x for c in M.list()]) - detM = self(Mx.determinant() % self._polynomial) - - R = detM.divisor() + sum(gaps)*W # ramification divisor - - return R, gaps - - @cached_method - def L_polynomial(self, name='t'): - """ - Return the L-polynomial of the function field. - - INPUT: - - - ``name`` -- (default: ``t``) name of the variable of the polynomial - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: F.L_polynomial() # optional - sage.libs.pari - 2*t^2 + t + 1 - """ - from sage.rings.integer_ring import ZZ - q = self.constant_field().order() - g = self.genus() - - B = [len(self.places(i+1)) for i in range(g)] - N = [sum(d * B[d-1] for d in ZZ(i+1).divisors()) for i in range(g)] - S = [N[i] - q**(i+1) - 1 for i in range(g)] - - a = [1] - for i in range(1, g+1): - a.append(sum(S[j] * a[i-j-1] for j in range(i)) / i) - for j in range(1, g+1): - a.append(q**j * a[g-j]) - - return ZZ[name](a) - - def number_of_rational_places(self, r=1): - """ - Return the number of rational places of the function field whose - constant field extended by degree ``r``. - - INPUT: - - - ``r`` -- positive integer (default: `1`) - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: F.number_of_rational_places() # optional - sage.libs.pari - 4 - sage: [F.number_of_rational_places(r) for r in [1..10]] # optional - sage.libs.pari - [4, 8, 4, 16, 44, 56, 116, 288, 508, 968] - """ - from sage.rings.integer_ring import IntegerRing - - q = self.constant_field().order() - L = self.L_polynomial() - Lp = L.derivative() - - R = IntegerRing()[[L.parent().gen()]] # power series ring - - f = R(Lp / L, prec=r) - n = f[r-1] + q**r + 1 - - return n - - -@handle_AA_and_QQbar -def _singular_normal(ideal): - r""" - Compute the normalization of the affine algebra defined by ``ideal`` using - Singular. - - The affine algebra is the quotient algebra of a multivariate polynomial - ring `R` by the ideal. The normalization is by definition the integral - closure of the algebra in its total ring of fractions. - - INPUT: - - - ``ideal`` -- a radical ideal in a multivariate polynomial ring - - OUTPUT: - - a list of lists, one list for each ideal in the equidimensional - decomposition of the ``ideal``, each list giving a set of generators of the - normalization of each ideal as an R-module by dividing all elements of the - list by the final element. Thus the list ``[x, y]`` means that `\{x/y, 1\}` - is the set of generators of the normalization of `R/(x,y)`. - - ALGORITHM: - - Singular's implementation of the normalization algorithm described in G.-M. - Greuel, S. Laplagne, F. Seelisch: Normalization of Rings (2009). - - EXAMPLES:: - - sage: from sage.rings.function_field.function_field import _singular_normal - sage: R. = QQ[] - - sage: f = (x^2 - y^3) * x - sage: _singular_normal(ideal(f)) # optional - sage.libs.singular - [[x, y], [1]] - - sage: f = y^2 - x - sage: _singular_normal(ideal(f)) # optional - sage.libs.singular - [[1]] - """ - from sage.libs.singular.function import singular_function, lib - lib('normal.lib') - normal = singular_function('normal') - execute = singular_function('execute') - - try: - get_printlevel = singular_function('get_printlevel') - except NameError: - execute('proc get_printlevel {return (printlevel);}') - get_printlevel = singular_function('get_printlevel') - - # It's fairly verbose unless printlevel is -1. - saved_printlevel = get_printlevel() - execute('printlevel=-1') - nor = normal(ideal) - execute('printlevel={}'.format(saved_printlevel)) - - return nor[1] - - -class FunctionField_integral(FunctionField_simple): - """ - Integral function fields. - - A function field is integral if it is defined by an irreducible separable - polynomial, which is integral over the maximal order of the base rational - function field. - """ - def _maximal_order_basis(self): - """ - Return a basis of the maximal order of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari - sage: F._maximal_order_basis() # optional - sage.libs.pari - [1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y] - - The basis of the maximal order *always* starts with 1. This is assumed - in some algorithms. - """ - from sage.matrix.constructor import matrix - from .hermite_form_polynomial import reversed_hermite_form - - k = self.constant_base_field() - K = self.base_field() # rational function field - n = self.degree() - - # Construct the defining polynomial of the function field as a - # two-variate polynomial g in the ring k[y,x] where k is the constant - # base field. - S,(y,x) = PolynomialRing(k, names='y,x', order='lex').objgens() - v = self.polynomial().list() - g = sum([v[i].numerator().subs(x) * y**i for i in range(len(v))]) - - if self.is_global(): - from sage.libs.singular.function import singular_function, lib - from sage.env import SAGE_EXTCODE - lib(SAGE_EXTCODE + '/singular/function_field/core.lib') - normalize = singular_function('core_normalize') - - # Singular "normalP" algorithm assumes affine domain over - # a prime field. So we construct gflat lifting g as in - # k_prime[yy,xx,zz]/(k_poly) where k = k_prime[zz]/(k_poly) - R = PolynomialRing(k.prime_subfield(), names='yy,xx,zz') - gflat = R.zero() - for m in g.monomials(): - c = g.monomial_coefficient(m).polynomial('zz') - gflat += R(c) * R(m) # R(m) is a monomial in yy and xx - - k_poly = R(k.polynomial('zz')) - - # invoke Singular - pols_in_R = normalize(R.ideal([k_poly, gflat])) - - # reconstruct polynomials in S - h = R.hom([y,x,k.gen()],S) - pols_in_S = [h(f) for f in pols_in_R] - else: - # Call Singular. Singular's "normal" function returns a basis - # of the integral closure of k(x,y)/(g) as a k[x,y]-module. - pols_in_S = _singular_normal(S.ideal(g))[0] - - # reconstruct the polynomials in the function field - x = K.gen() - y = self.gen() - pols = [] - for f in pols_in_S: - p = f.polynomial(S.gen(0)) - s = 0 - for i in range(p.degree()+1): - s += p[i].subs(x) * y**i - pols.append(s) - - # Now if pols = [g1,g2,...gn,g0], then the g1/g0,g2/g0,...,gn/g0, - # and g0/g0=1 are the module generators of the integral closure - # of the equation order Sb = k[xb,yb] in its fraction field, - # that is, the function field. The integral closure of k[x] - # is then obtained by multiplying these generators with powers of y - # as the equation order itself is an integral extension of k[x]. - d = ~ pols[-1] - _basis = [] - for f in pols: - b = d * f - for i in range(n): - _basis.append(b) - b *= y - - # Finally we reduce _basis to get a basis over k[x]. This is done of - # course by Hermite normal form computation. Here we apply a trick to - # get a basis that starts with 1 and is ordered in increasing - # y-degrees. The trick is to use the reversed Hermite normal form. - # Note that it is important that the overall denominator l lies in k[x]. - V, fr_V, to_V = self.free_module() - basis_V = [to_V(bvec) for bvec in _basis] - l = lcm([vvec.denominator() for vvec in basis_V]) - - _mat = matrix([[coeff.numerator() for coeff in l*v] for v in basis_V]) - reversed_hermite_form(_mat) - - basis = [fr_V(v) / l for v in _mat if not v.is_zero()] - return basis - - @cached_method - def equation_order(self): - """ - Return the equation order of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.equation_order() # optional - sage.libs.pari - Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 - - sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: F.equation_order() # optional - sage.libs.singular - Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 - """ - from .order import FunctionFieldOrder_basis - a = self.gen() - basis = [a**i for i in range(self.degree())] - return FunctionFieldOrder_basis(tuple(basis)) - - @cached_method - def primitive_integal_element_infinite(self): - """ - Return a primitive integral element over the base maximal infinite order. - - This element is integral over the maximal infinite order of the base - rational function field and the function field is a simple extension by - this element over the base order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: b = F.primitive_integal_element_infinite(); b # optional - sage.libs.pari - 1/x^2*y - sage: b.minimal_polynomial('t') # optional - sage.libs.pari - t^3 + (x^4 + x^2 + 1)/x^4 - """ - f = self.polynomial() - n = f.degree() - y = self.gen() - x = self.base_field().gen() - - cf = max([(f[i].numerator().degree()/(n-i)).ceil() for i in range(n) - if f[i] != 0]) - return y*x**(-cf) - - @cached_method - def equation_order_infinite(self): - """ - Return the infinite equation order of the function field. - - This is by definition `o[b]` where `b` is the primitive integral - element from :meth:`primitive_integal_element_infinite()` and `o` is - the maximal infinite order of the base rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.equation_order_infinite() # optional - sage.libs.pari - Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 - - sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: F.equation_order_infinite() # optional - sage.libs.singular - Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 - """ - from .order import FunctionFieldOrderInfinite_basis - b = self.primitive_integal_element_infinite() - basis = [b**i for i in range(self.degree())] - return FunctionFieldOrderInfinite_basis(tuple(basis)) - - -class FunctionField_char_zero_integral(FunctionField_char_zero, FunctionField_integral): - """ - Function fields of characteristic zero, defined by an irreducible and - separable polynomial, integral over the maximal order of the base rational - function field with a finite constant field. - """ - pass - - -class FunctionField_global_integral(FunctionField_global, FunctionField_integral): - """ - Global function fields, defined by an irreducible and separable polynomial, - integral over the maximal order of the base rational function field with a - finite constant field. - """ - pass - - -class RationalFunctionField(FunctionField): - """ - Rational function field in one variable, over an arbitrary base field. - - INPUT: - - - ``constant_field`` -- arbitrary field - - - ``names`` -- string or tuple of length 1 - - EXAMPLES:: - - sage: K. = FunctionField(GF(3)); K # optional - sage.libs.pari - Rational function field in t over Finite Field of size 3 - sage: K.gen() # optional - sage.libs.pari - t - sage: 1/t + t^3 + 5 # optional - sage.libs.pari - (t^4 + 2*t + 1)/t - - sage: K. = FunctionField(QQ); K - Rational function field in t over Rational Field - sage: K.gen() - t - sage: 1/t + t^3 + 5 - (t^4 + 5*t + 1)/t - - There are various ways to get at the underlying fields and rings - associated to a rational function field:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.base_field() # optional - sage.libs.pari - Rational function field in t over Finite Field of size 7 - sage: K.field() # optional - sage.libs.pari - Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 - sage: K.constant_field() # optional - sage.libs.pari - Finite Field of size 7 - sage: K.maximal_order() # optional - sage.libs.pari - Maximal order of Rational function field in t over Finite Field of size 7 - - sage: K. = FunctionField(QQ) - sage: K.base_field() - Rational function field in t over Rational Field - sage: K.field() - Fraction Field of Univariate Polynomial Ring in t over Rational Field - sage: K.constant_field() - Rational Field - sage: K.maximal_order() - Maximal order of Rational function field in t over Rational Field - - We define a morphism:: - - sage: K. = FunctionField(QQ) - sage: L = FunctionField(QQ, 'tbar') # give variable name as second input - sage: K.hom(L.gen()) - Function Field morphism: - From: Rational function field in t over Rational Field - To: Rational function field in tbar over Rational Field - Defn: t |--> tbar - - Here are some calculations over a number field:: - - sage: R. = FunctionField(QQ) - sage: L. = R[] - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular - sage: (y/x).divisor() # optional - sage.libs.singular sage.modules - - Place (x, y - 1) - - Place (x, y + 1) - + Place (x^2 + 1, y) - - sage: A. = QQ[] # optional - sage.rings.number_field - sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field - sage: R. = FunctionField(NF) # optional - sage.rings.number_field - sage: L. = R[] # optional - sage.rings.number_field - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular sage.modules sage.rings.number_field - - sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field - -2*Place (1/x, 1/x*y - 1) - - 2*Place (1/x, 1/x*y + 1) - + Place (x, y - 1) - + Place (x, y + 1) - - sage: (x/y).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field - - Place (x - i, y) - + Place (x, y - 1) - + Place (x, y + 1) - - Place (x + i, y) - - """ - Element = FunctionFieldElement_rational - - def __init__(self, constant_field, names, category=None): - """ - Initialize. - - EXAMPLES:: - - sage: K. = FunctionField(CC); K - Rational function field in t over Complex Field with 53 bits of precision - sage: TestSuite(K).run() # long time (5s) - - sage: FunctionField(QQ[I], 'alpha') # optional - sage.rings.number_field - Rational function field in alpha over - Number Field in I with defining polynomial x^2 + 1 with I = 1*I - - Must be over a field:: - - sage: FunctionField(ZZ, 't') - Traceback (most recent call last): - ... - TypeError: constant_field must be a field - """ - if names is None: - raise ValueError("variable name must be specified") - elif not isinstance(names, tuple): - names = (names, ) - if not constant_field.is_field(): - raise TypeError("constant_field must be a field") - - self._constant_field = constant_field - - FunctionField.__init__(self, self, names=names, category=FunctionFields().or_subcategory(category)) - - from .place import FunctionFieldPlace_rational - self._place_class = FunctionFieldPlace_rational - - R = constant_field[names[0]] - self._hash = hash((constant_field, names)) - self._ring = R - self._field = R.fraction_field() - - hom = Hom(self._field, self) - from .maps import FractionFieldToFunctionField - self.register_coercion(hom.__make_element_class__(FractionFieldToFunctionField)(hom.domain(), hom.codomain())) - - from sage.categories.sets_with_partial_maps import SetsWithPartialMaps - from sage.categories.morphism import SetMorphism - R.register_conversion(SetMorphism(self.Hom(R, SetsWithPartialMaps()), self._to_polynomial)) - - self._gen = self(R.gen()) - - def __reduce__(self): - """ - Return the arguments which were used to create this instance. The - rationale for this is explained in the documentation of - :class:`UniqueRepresentation`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: clazz,args = K.__reduce__() - sage: clazz(*args) - Rational function field in x over Rational Field - """ - from .constructor import FunctionField - return FunctionField, (self._constant_field, self._names) - - def __hash__(self): - """ - Return hash of the function field. - - The hash is formed from the constant field and the variable names. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: hash(K) == hash((K.constant_base_field(), K.variable_names())) - True - - """ - return self._hash - - def _repr_(self): - """ - Return string representation of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K._repr_() - 'Rational function field in t over Rational Field' - """ - return "Rational function field in %s over %s"%( - self.variable_name(), self._constant_field) - - def _element_constructor_(self, x): - r""" - Coerce ``x`` into an element of the function field, possibly not canonically. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: a = K._element_constructor_(K.maximal_order().gen()); a - t - sage: a.parent() - Rational function field in t over Rational Field - - TESTS: - - Conversion of a string:: - - sage: K('t') - t - sage: K('1/t') - 1/t - - Conversion of a constant polynomial over the function field:: - - sage: K(K.polynomial_ring().one()) - 1 - - Some indirect test of conversion:: - - sage: S. = K[] - sage: I = S * [x^2 - y^2, y - t] # optional - sage.libs.singular - sage: I.groebner_basis() # optional - sage.libs.singular - [x^2 - t^2, y - t] - - """ - if isinstance(x, FunctionFieldElement): - return self.element_class(self, self._field(x._x)) - try: - x = self._field(x) - except TypeError as Err: - try: - if x.parent() is self.polynomial_ring(): - return x[0] - except AttributeError: - pass - raise Err - return self.element_class(self, x) - - def _to_constant_base_field(self, f): - r""" - Return ``f`` as an element of the constant base field. - - INPUT: - - - ``f`` -- element of the rational function field which is a - constant of the underlying rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K._to_constant_base_field(K(1)) - 1 - sage: K._to_constant_base_field(K(x)) - Traceback (most recent call last): - ... - ValueError: only constants can be converted into the constant base field but x is not a constant - - TESTS: - - Verify that :trac:`21872` has been resolved:: - - sage: K(1) in QQ - True - sage: x in QQ - False - - """ - K = self.constant_base_field() - if f.denominator() in K and f.numerator() in K: - # When K is not exact, f.denominator() might not be an exact 1, so - # we need to divide explicitly to get the correct precision - return K(f.numerator()) / K(f.denominator()) - raise ValueError("only constants can be converted into the constant base field but %r is not a constant"%(f,)) - - def _to_polynomial(self, f): - """ - If ``f`` is integral, return it as a polynomial. - - INPUT: - - - ``f`` -- an element of this rational function field whose denominator is a constant. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K._ring(x) # indirect doctest - x - """ - K = f.parent().constant_base_field() - if f.denominator() in K: - return f.numerator()/K(f.denominator()) - raise ValueError("only polynomials can be converted to the underlying polynomial ring") - - def _to_bivariate_polynomial(self, f): - """ - Convert ``f`` from a univariate polynomial over the rational function - field into a bivariate polynomial and a denominator. - - INPUT: - - - ``f`` -- univariate polynomial over the function field - - OUTPUT: - - - bivariate polynomial, denominator - - EXAMPLES:: - - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari - sage: R._to_bivariate_polynomial(f) # optional - sage.libs.pari - (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) - """ - v = f.list() - denom = lcm([a.denominator() for a in v]) - S = denom.parent() - x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens() - phi = S.hom([t]) - return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom - - def _factor_univariate_polynomial(self, f, proof=None): - """ - Factor the univariate polynomial f over the function field. - - INPUT: - - - ``f`` -- univariate polynomial over the function field - - EXAMPLES: - - We do a factorization over the function field over the rationals:: - - sage: R. = FunctionField(QQ) - sage: S. = R[] - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) - sage: f.factor() # indirect doctest # optional - sage.libs.singular - (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2) - sage: f.factor().prod() == f # optional - sage.libs.singular - True - - We do a factorization over a finite prime field:: - - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari - sage: f.factor() # optional - sage.libs.pari - (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t) - sage: f.factor().prod() == f # optional - sage.libs.pari - True - - Factoring over a function field over a non-prime finite field:: - - sage: k. = GF(9) # optional - sage.libs.pari - sage: R. = FunctionField(k) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^3 - a*t^3) # optional - sage.libs.pari - sage: f.factor() # optional - sage.libs.pari - (1/t) * (X + (a + 2)*t)^3 - sage: f.factor().prod() == f # optional - sage.libs.pari - True - - Factoring over a function field over a tower of finite fields:: - - sage: k. = GF(4) # optional - sage.libs.pari - sage: R. = k[] # optional - sage.libs.pari - sage: l. = k.extension(b^2 + b + a) # optional - sage.libs.pari - sage: K. = FunctionField(l) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: F = t*x # optional - sage.libs.pari - sage: F.factor(proof=False) # optional - sage.libs.pari - (x) * t - - """ - old_variable_name = f.variable_name() - # the variables of the bivariate polynomial must be distinct - if self.variable_name() == f.variable_name(): - # replace x with xx to make the variable names distinct - f = f.change_variable_name(old_variable_name + old_variable_name) - - F, d = self._to_bivariate_polynomial(f) - fac = F.factor(proof=proof) - x = f.parent().gen() - t = f.parent().base_ring().gen() - phi = F.parent().hom([x, t]) - v = [(phi(P),e) for P, e in fac] - unit = phi(fac.unit())/d - w = [] - for a, e in v: - c = a.leading_coefficient() - a = a/c - # undo any variable substitution that we introduced for the bivariate polynomial - if old_variable_name != a.variable_name(): - a = a.change_variable_name(old_variable_name) - unit *= (c**e) - if a.is_unit(): - unit *= a**e - else: - w.append((a,e)) - from sage.structure.factorization import Factorization - return Factorization(w, unit=unit) - - def extension(self, f, names=None): - """ - Create an extension `L = K[y]/(f(y))` of the rational function field. - - INPUT: - - - ``f`` -- univariate polynomial over self - - - ``names`` -- string or length-1 tuple - - OUTPUT: - - - a function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular - Function field in y defined by y^5 + x*y - x^3 - 3*x - - A nonintegral defining polynomial:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular - Function field in y defined by y^3 + 1/t*y + t^3/(t + 1) - - The defining polynomial need not be monic or integral:: - - sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular - Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) - """ - from . import constructor - return constructor.FunctionFieldExtension(f, names) - - @cached_method - def polynomial_ring(self, var='x'): - """ - Return a polynomial ring in one variable over the rational function field. - - INPUT: - - - ``var`` -- string; name of the variable - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.polynomial_ring() - Univariate Polynomial Ring in x over Rational function field in x over Rational Field - sage: K.polynomial_ring('T') - Univariate Polynomial Ring in T over Rational function field in x over Rational Field - """ - return self[var] - - @cached_method(key=lambda self, base, basis, map: map) - def free_module(self, base=None, basis=None, map=True): - """ - Return a vector space `V` and isomorphisms from the field to `V` and - from `V` to the field. - - This function allows us to identify the elements of this field with - elements of a one-dimensional vector space over the field itself. This - method exists so that all function fields (rational or not) have the - same interface. - - INPUT: - - - ``base`` -- the base field of the vector space; must be the function - field itself (the default) - - - ``basis`` -- (ignored) a basis for the vector space - - - ``map`` -- (default ``True``), whether to return maps to and from the vector space - - OUTPUT: - - - a vector space `V` over base field - - - an isomorphism from `V` to the field - - - the inverse isomorphism from the field to `V` - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.free_module() # optional - sage.modules - (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: - From: Vector space of dimension 1 over Rational function field in x over Rational Field - To: Rational function field in x over Rational Field, Isomorphism: - From: Rational function field in x over Rational Field - To: Vector space of dimension 1 over Rational function field in x over Rational Field) - - TESTS:: - - sage: K.free_module() # optional - sage.modules - (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: - From: Vector space of dimension 1 over Rational function field in x over Rational Field - To: Rational function field in x over Rational Field, Isomorphism: - From: Rational function field in x over Rational Field - To: Vector space of dimension 1 over Rational function field in x over Rational Field) - - """ - if basis is not None: - raise NotImplementedError - from .maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace - if base is None: - base = self - elif base is not self: - raise ValueError("base must be the rational function field itself") - V = base**1 - if not map: - return V - from_V = MapVectorSpaceToFunctionField(V, self) - to_V = MapFunctionFieldToVectorSpace(self, V) - return (V, from_V, to_V) - - def random_element(self, *args, **kwds): - """ - Create a random element of the rational function field. - - Parameters are passed to the random_element method of the - underlying fraction field. - - EXAMPLES:: - - sage: FunctionField(QQ,'alpha').random_element() # random - (-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95) - """ - return self(self._field.random_element(*args, **kwds)) - - def degree(self, base=None): - """ - Return the degree over the base field of the rational function - field. Since the base field is the rational function field itself, the - degree is 1. - - INPUT: - - - ``base`` -- the base field of the vector space; must be the function - field itself (the default) - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.degree() - 1 - """ - if base is None: - base = self - elif base is not self: - raise ValueError("base must be the rational function field itself") - from sage.rings.integer_ring import ZZ - return ZZ(1) - - def gen(self, n=0): - """ - Return the ``n``-th generator of the function field. If ``n`` is not - 0, then an IndexError is raised. - - EXAMPLES:: - - sage: K. = FunctionField(QQ); K.gen() - t - sage: K.gen().parent() - Rational function field in t over Rational Field - sage: K.gen(1) - Traceback (most recent call last): - ... - IndexError: Only one generator. - """ - if n != 0: - raise IndexError("Only one generator.") - return self._gen - - def ngens(self): - """ - Return the number of generators, which is 1. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.ngens() - 1 - """ - return 1 - - def base_field(self): - """ - Return the base field of the rational function field, which is just - the function field itself. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.base_field() # optional - sage.libs.pari - Rational function field in t over Finite Field of size 7 - """ - return self - - def hom(self, im_gens, base_morphism=None): - """ - Create a homomorphism from ``self`` to another ring. - - INPUT: - - - ``im_gens`` -- exactly one element of some ring. It must be - invertible and transcendental over the image of - ``base_morphism``; this is not checked. - - - ``base_morphism`` -- a homomorphism from the base field into the - other ring. If ``None``, try to use a coercion map. - - OUTPUT: - - - a map between function fields - - EXAMPLES: - - We make a map from a rational function field to itself:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.hom( (x^4 + 2)/x) # optional - sage.libs.pari - Function Field endomorphism of Rational function field in x over Finite Field of size 7 - Defn: x |--> (x^4 + 2)/x - - We construct a map from a rational function field into a - non-rational extension field:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari - Function Field morphism: - From: Rational function field in x over Finite Field of size 7 - To: Function field in y defined by y^3 + 6*x^3 + x - Defn: x |--> y^2 + y + 2 - sage: f(x) # optional - sage.libs.pari - y^2 + y + 2 - sage: f(x^2) # optional - sage.libs.pari - 5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4 - """ - if isinstance(im_gens, CategoryObject): - return self.Hom(im_gens).natural_map() - if not isinstance(im_gens, (list,tuple)): - im_gens = [im_gens] - if len(im_gens) != 1: - raise ValueError("there must be exactly one generator") - x = im_gens[0] - R = x.parent() - if base_morphism is None and not R.has_coerce_map_from(self.constant_field()): - raise ValueError("you must specify a morphism on the base field") - from .maps import FunctionFieldMorphism_rational - return FunctionFieldMorphism_rational(self.Hom(R), x, base_morphism) - - def field(self): - """ - Return the underlying field, forgetting the function field - structure. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.field() # optional - sage.libs.pari - Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 - - .. SEEALSO:: - - :meth:`sage.rings.fraction_field.FractionField_1poly_field.function_field` - - """ - return self._field - - @cached_method - def maximal_order(self): - """ - Return the maximal order of the function field. - - Since this is a rational function field it is of the form `K(t)`, and the - maximal order is by definition `K[t]`, where `K` is the constant field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.maximal_order() - Maximal order of Rational function field in t over Rational Field - sage: K.equation_order() - Maximal order of Rational function field in t over Rational Field - """ - from .order import FunctionFieldMaximalOrder_rational - return FunctionFieldMaximalOrder_rational(self) - - equation_order = maximal_order - - @cached_method - def maximal_order_infinite(self): - """ - Return the maximal infinite order of the function field. - - By definition, this is the valuation ring of the degree valuation of - the rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.maximal_order_infinite() - Maximal infinite order of Rational function field in t over Rational Field - sage: K.equation_order_infinite() - Maximal infinite order of Rational function field in t over Rational Field - """ - from .order import FunctionFieldMaximalOrderInfinite_rational - return FunctionFieldMaximalOrderInfinite_rational(self) - - equation_order_infinite = maximal_order_infinite - - def constant_base_field(self): - """ - Return the field of which the rational function field is a - transcendental extension. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.constant_base_field() - Rational Field - """ - return self._constant_field - - constant_field = constant_base_field - - def different(self): - """ - Return the different of the rational function field. - - For a rational function field, the different is simply the zero - divisor. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.different() # optional - sage.modules - 0 - """ - return self.divisor_group().zero() - - def genus(self): - """ - Return the genus of the function field, namely 0. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.genus() - 0 - """ - return Integer(0) - - def change_variable_name(self, name): - r""" - Return a field isomorphic to this field with variable ``name``. - - INPUT: - - - ``name`` -- a string or a tuple consisting of a single string, the - name of the new variable - - OUTPUT: - - A triple ``F,f,t`` where ``F`` is a rational function field, ``f`` is - an isomorphism from ``F`` to this field, and ``t`` is the inverse of - ``f``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: L,f,t = K.change_variable_name('y') - sage: L,f,t - (Rational function field in y over Rational Field, - Function Field morphism: - From: Rational function field in y over Rational Field - To: Rational function field in x over Rational Field - Defn: y |--> x, - Function Field morphism: - From: Rational function field in x over Rational Field - To: Rational function field in y over Rational Field - Defn: x |--> y) - sage: L.change_variable_name('x')[0] is K - True - - """ - if isinstance(name, tuple): - if len(name) != 1: - raise ValueError("names must be a tuple with a single string") - name = name[0] - if name == self.variable_name(): - id = Hom(self,self).identity() - return self,id,id - else: - from .constructor import FunctionField - ret = FunctionField(self.constant_base_field(), name) - return ret, ret.hom(self.gen()), self.hom(ret.gen()) - - def residue_field(self, place, name=None): - """ - Return the residue field of the place along with the maps from - and to it. - - INPUT: - - - ``place`` -- place of the function field - - - ``name`` -- string; name of the generator of the residue field - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: p = F.places_finite(2)[0] # optional - sage.libs.pari - sage: R, fr_R, to_R = F.residue_field(p) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari - Finite Field in z2 of size 5^2 - sage: to_R(x) in R # optional - sage.libs.pari - True - """ - return place.residue_field(name=name) - - -class RationalFunctionField_char_zero(RationalFunctionField): - """ - Rational function fields of characteristic zero. - """ - @cached_method - def higher_derivation(self): - """ - Return the higher derivation for the function field. - - This is also called the Hasse-Schmidt derivation. - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: d = F.higher_derivation() # optional - sage.modules - sage: [d(x^5,i) for i in range(10)] # optional - sage.modules - [x^5, 5*x^4, 10*x^3, 10*x^2, 5*x, 1, 0, 0, 0, 0] - sage: [d(x^9,i) for i in range(10)] # optional - sage.modules - [x^9, 9*x^8, 36*x^7, 84*x^6, 126*x^5, 126*x^4, 84*x^3, 36*x^2, 9*x, 1] - """ - from .derivations import FunctionFieldHigherDerivation_char_zero - return FunctionFieldHigherDerivation_char_zero(self) - - -class RationalFunctionField_global(RationalFunctionField): - """ - Rational function field over finite fields. - """ - _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') - - def places(self, degree=1): - """ - Return all places of the degree. - - INPUT: - - - ``degree`` -- (default: 1) a positive integer - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari - [Place (1/x), - Place (x), - Place (x + 1), - Place (x + 2), - Place (x + 3), - Place (x + 4)] - """ - if degree == 1: - return [self.place_infinite()] + self.places_finite(degree) - else: - return self.places_finite(degree) - - def places_finite(self, degree=1): - """ - Return the finite places of the degree. - - INPUT: - - - ``degree`` -- (default: 1) a positive integer - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.places_finite() # optional - sage.libs.pari - [Place (x), Place (x + 1), Place (x + 2), Place (x + 3), Place (x + 4)] - """ - return list(self._places_finite(degree)) - - def _places_finite(self, degree=1): - """ - Return a generator for all monic irreducible polynomials of the degree. - - INPUT: - - - ``degree`` -- (default: 1) a positive integer - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F._places_finite() # optional - sage.libs.pari - - """ - O = self.maximal_order() - R = O._ring - G = R.polynomials(max_degree=degree - 1) - lm = R.monomial(degree) - for g in G: - h = lm + g - if h.is_irreducible(): - yield O.ideal(h).place() - - def place_infinite(self): - """ - Return the unique place at infinity. - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.place_infinite() # optional - sage.libs.pari - Place (1/x) - """ - return self.maximal_order_infinite().prime_ideal().place() - - def get_place(self, degree): - """ - Return a place of ``degree``. - - INPUT: - - - ``degree`` -- a positive integer - - EXAMPLES:: - - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: K.get_place(1) # optional - sage.libs.pari - Place (x) - sage: K.get_place(2) # optional - sage.libs.pari - Place (x^2 + x + 1) - sage: K.get_place(3) # optional - sage.libs.pari - Place (x^3 + x + 1) - sage: K.get_place(4) # optional - sage.libs.pari - Place (x^4 + x + 1) - sage: K.get_place(5) # optional - sage.libs.pari - Place (x^5 + x^2 + 1) - - """ - for p in self._places_finite(degree): - return p - - assert False, "there is a bug around" - - @cached_method - def higher_derivation(self): - """ - Return the higher derivation for the function field. - - This is also called the Hasse-Schmidt derivation. - - EXAMPLES:: - - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: d = F.higher_derivation() # optional - sage.libs.pari - sage: [d(x^5,i) for i in range(10)] # optional - sage.libs.pari - [x^5, 0, 0, 0, 0, 1, 0, 0, 0, 0] - sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari - [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] - """ - from .derivations import RationalFunctionFieldHigherDerivation_global - return RationalFunctionFieldHigherDerivation_global(self) diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py deleted file mode 100644 index b12090991ee..00000000000 --- a/src/sage/rings/function_field/function_field_valuation.py +++ /dev/null @@ -1,1482 +0,0 @@ -# -*- coding: utf-8 -*- -r""" -Discrete valuations on function fields - -AUTHORS: - -- Julian Rüth (2016-10-16): initial version - -EXAMPLES: - -We can create classical valuations that correspond to finite and infinite -places on a rational function field:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1); v - (x - 1)-adic valuation - sage: v = K.valuation(x^2 + 1); v - (x^2 + 1)-adic valuation - sage: v = K.valuation(1/x); v - Valuation at the infinite place - -Note that we can also specify valuations which do not correspond to a place of -the function field:: - - sage: R. = QQ[] - sage: w = valuations.GaussValuation(R, QQ.valuation(2)) - sage: v = K.valuation(w); v - 2-adic valuation - -Valuations on a rational function field can then be extended to finite -extensions:: - - sage: v = K.valuation(x - 1); v - (x - 1)-adic valuation - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: w = v.extensions(L); w # optional - sage.libs.singular - [[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation, - [ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation] - -TESTS: - -Run test suite for classical places over rational function fields:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1) - sage: TestSuite(v).run(max_runs=100) # long time - - sage: v = K.valuation(x^2 + 1) - sage: TestSuite(v).run(max_runs=100) # long time - - sage: v = K.valuation(1/x) - sage: TestSuite(v).run(max_runs=100) # long time - -Run test suite over classical places of finite extensions:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x - 1) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: ws = v.extensions(L) # optional - sage.libs.singular - sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # optional - sage.libs.singular - -Run test suite for valuations that do not correspond to a classical place:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: v = GaussValuation(R, QQ.valuation(2)) - sage: w = K.valuation(v) - sage: TestSuite(w).run() # long time - -Run test suite for a non-classical valuation that does not correspond to an -affinoid contained in the unit disk:: - - sage: w = K.valuation((w, K.hom(K.gen()/2), K.hom(2*K.gen()))); w - 2-adic valuation (in Rational function field in x over Rational Field after x |--> 1/2*x) - sage: TestSuite(w).run() # long time - -Run test suite for some other classical places over large ground fields:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: M. = FunctionField(K) # optional - sage.libs.pari - sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari - sage: TestSuite(v).run(max_runs=10) # long time # optional - sage.libs.pari - -Run test suite for extensions over the infinite place:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1/x) - sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular - sage: w = v.extensions(L) # optional - sage.libs.singular - sage: TestSuite(w).run() # long time # optional - sage.libs.singular - -Run test suite for a valuation with `v(1/x) > 0` which does not come from a -classical valuation of the infinite place:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) - sage: w = K.valuation(w) - sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) - sage: TestSuite(v).run() # long time - -Run test suite for extensions which come from the splitting in the base field:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) - sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: ws = v.extensions(L) # optional - sage.libs.singular - sage: for w in ws: TestSuite(w).run(max_runs=100) # long time - -Run test suite for a finite place with residual degree and ramification:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: L. = FunctionField(K) # optional - sage.libs.pari - sage: v = L.valuation(x^6 - t) # optional - sage.libs.pari - sage: TestSuite(v).run(max_runs=10) # long time - -Run test suite for a valuation which is backed by limit valuation:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) - sage: v = K.valuation(x - 1) - sage: w = v.extension(L) # optional - sage.libs.singular - sage: TestSuite(w).run() # long time # optional - sage.libs.singular - -Run test suite for a valuation which sends an element to `-\infty`:: - - sage: R. = QQ[] - sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity) - sage: K. = FunctionField(QQ) - sage: w = K.valuation(v) - sage: TestSuite(w).run() # long time - -REFERENCES: - -An overview of some computational tools relating to valuations on function -fields can be found in Section 4.6 of [Rüt2014]_. Most of this was originally -developed for number fields in [Mac1936I]_ and [Mac1936II]_. - -""" -# **************************************************************************** -# Copyright (C) 2016-2018 Julian Rüth -# -# Distributed under the terms of the GNU General Public License (GPL) -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# https://www.gnu.org/licenses/ -# **************************************************************************** -from sage.structure.factory import UniqueFactory -from sage.rings.rational_field import QQ -from sage.misc.cachefunc import cached_method - -from sage.rings.valuation.valuation import DiscreteValuation, DiscretePseudoValuation, InfiniteDiscretePseudoValuation, NegativeInfiniteDiscretePseudoValuation -from sage.rings.valuation.trivial_valuation import TrivialValuation -from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation, MappedValuation_base - -class FunctionFieldValuationFactory(UniqueFactory): - r""" - Create a valuation on ``domain`` corresponding to ``prime``. - - INPUT: - - - ``domain`` -- a function field - - - ``prime`` -- a place of the function field, a valuation on a subring, or - a valuation on another function field together with information for - isomorphisms to and from that function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1); v # indirect doctest - (x - 1)-adic valuation - sage: v(x) - 0 - sage: v(x - 1) - 1 - - See :meth:`sage.rings.function_field.function_field.FunctionField.valuation` for further examples. - - """ - def create_key_and_extra_args(self, domain, prime): - r""" - Create a unique key which identifies the valuation given by ``prime`` - on ``domain``. - - TESTS: - - We specify a valuation on a function field by two different means and - get the same object:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x - 1) # indirect doctest - - sage: R. = QQ[] - sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) - sage: K.valuation(w) is v - True - - The normalization is, however, not smart enough, to unwrap - substitutions that turn out to be trivial:: - - sage: w = GaussValuation(R, QQ.valuation(2)) - sage: w = K.valuation(w) - sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) - False - - """ - from sage.categories.function_fields import FunctionFields - if domain not in FunctionFields(): - raise ValueError("Domain must be a function field.") - - if isinstance(prime, tuple): - if len(prime) == 3: - # prime is a triple of a valuation on another function field with - # isomorphism information - return self.create_key_and_extra_args_from_valuation_on_isomorphic_field(domain, prime[0], prime[1], prime[2]) - - from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace - if prime.parent() is DiscretePseudoValuationSpace(domain): - # prime is already a valuation of the requested domain - # if we returned (domain, prime), we would break caching - # because this element has been created from a different key - # Instead, we return the key that was used to create prime - # so the caller gets back a correctly cached version of prime - if not hasattr(prime, "_factory_data"): - raise NotImplementedError("Valuations on function fields must be unique and come out of the FunctionFieldValuation factory but %r has been created by other means" % (prime,)) - return prime._factory_data[2], {} - - if prime in domain: - # prime defines a place - return self.create_key_and_extra_args_from_place(domain, prime) - if prime.parent() is DiscretePseudoValuationSpace(domain._ring): - # prime is a discrete (pseudo-)valuation on the polynomial ring - # that the domain is constructed from - return self.create_key_and_extra_args_from_valuation(domain, prime) - if domain.base_field() is not domain: - # prime might define a valuation on a subring of domain and have a - # unique extension to domain - base_valuation = domain.base_field().valuation(prime) - return self.create_key_and_extra_args_from_valuation(domain, base_valuation) - from sage.rings.ideal import is_Ideal - if is_Ideal(prime): - raise NotImplementedError("a place cannot be given by an ideal yet") - - raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r" % (prime, domain)) - - def create_key_and_extra_args_from_place(self, domain, generator): - r""" - Create a unique key which identifies the valuation at the place - specified by ``generator``. - - TESTS: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1/x) # indirect doctest - - """ - if generator not in domain.base_field(): - raise NotImplementedError("a place must be defined over a rational function field") - - if domain.base_field() is not domain: - # if this is an extension field, construct the unique place over - # the place on the subfield - return self.create_key_and_extra_args(domain, domain.base_field().valuation(generator)) - - if generator in domain.constant_base_field(): - # generator is a constant, we associate to it the place which - # corresponds to the polynomial (x - generator) - return self.create_key_and_extra_args(domain, domain.gen() - generator) - - if generator in domain._ring: - # generator is a polynomial - generator = domain._ring(generator) - if not generator.is_monic(): - raise ValueError("place must be defined by a monic polynomial but %r is not monic" % (generator,)) - if not generator.is_irreducible(): - raise ValueError("place must be defined by an irreducible polynomial but %r factors over %r" % (generator, domain._ring)) - # we construct the corresponding valuation on the polynomial ring - # with v(generator) = 1 - from sage.rings.valuation.gauss_valuation import GaussValuation - valuation = GaussValuation(domain._ring, TrivialValuation(domain.constant_base_field())).augmentation(generator, 1) - return self.create_key_and_extra_args(domain, valuation) - elif generator == ~domain.gen(): - # generator is 1/x, the infinite place - return (domain, (domain.valuation(domain.gen()), domain.hom(~domain.gen()), domain.hom(~domain.gen()))), {} - else: - raise ValueError("a place must be given by an irreducible polynomial or the inverse of the generator; %r does not define a place over %r" % (generator, domain)) - - def create_key_and_extra_args_from_valuation(self, domain, valuation): - r""" - Create a unique key which identifies the valuation which extends - ``valuation``. - - TESTS: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) - sage: v = K.valuation(w) # indirect doctest - - Check that :trac:`25294` has been resolved:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) # optional - sage.libs.singular - sage: v = K.valuation(x) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular - [[ (x)-adic valuation, v(y) = 1 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y), - [ (x)-adic valuation, v(y) = 1/2 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)] - - """ - # this should have been handled by create_key already - assert valuation.domain() is not domain - - if valuation.domain() is domain._ring: - if domain.base_field() is not domain: - vK = valuation.restriction(valuation.domain().base_ring()) - if vK.domain() is not domain.base_field(): - raise ValueError("valuation must extend a valuation on the base field but %r extends %r whose domain is not %r" % (valuation, vK, domain.base_field())) - # Valuation is an approximant that describes a single valuation - # on domain. - # For uniqueness of valuations (which provides better caching - # and easier pickling) we need to find a normal form of - # valuation, i.e., the smallest approximant that describes this - # valuation - approximants = vK.mac_lane_approximants(domain.polynomial(), require_incomparability=True) - approximant = vK.mac_lane_approximant(domain.polynomial(), valuation, approximants) - return (domain, approximant), {'approximants': approximants} - else: - # on a rational function field K(x), any valuation on K[x] that - # does not have an element with valuation -infty extends to a - # pseudo-valuation on K(x) - if valuation.is_negative_pseudo_valuation(): - raise ValueError("there must not be an element of valuation -Infinity in the domain of valuation %r" % (valuation,)) - return (domain, valuation), {} - - if valuation.domain().is_subring(domain.base_field()): - # valuation is defined on a subring of this function field, try to lift it - return self.create_key_and_extra_args(domain, valuation.extension(domain)) - - raise NotImplementedError("extension of valuation from %r to %r not implemented yet" % (valuation.domain(), domain)) - - def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, valuation, to_valuation_domain, from_valuation_domain): - r""" - Create a unique key which identifies the valuation which is - ``valuation`` after mapping through ``to_valuation_domain``. - - TESTS:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.libs.singular - sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.libs.singular - sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.libs.singular - - """ - from sage.categories.function_fields import FunctionFields - if valuation.domain() not in FunctionFields(): - raise ValueError("valuation must be defined over an isomorphic function field but %r is not a function field" % (valuation.domain(),)) - - from sage.categories.homset import Hom - if to_valuation_domain not in Hom(domain, valuation.domain()): - raise ValueError("to_valuation_domain must map from %r to %r but %r maps from %r to %r" % (domain, valuation.domain(), to_valuation_domain, to_valuation_domain.domain(), to_valuation_domain.codomain())) - if from_valuation_domain not in Hom(valuation.domain(), domain): - raise ValueError("from_valuation_domain must map from %r to %r but %r maps from %r to %r" % (valuation.domain(), domain, from_valuation_domain, from_valuation_domain.domain(), from_valuation_domain.codomain())) - - if domain is domain.base(): - if valuation.domain() is not valuation.domain().base() or valuation.domain().constant_base_field() != domain.constant_base_field(): - raise NotImplementedError("maps must be isomorphisms with a rational function field over the same base field, not with %r" % (valuation.domain(),)) - if domain != valuation.domain(): - # make it harder to create different representations of the same valuation - # (nothing bad happens if we did, but >= and <= are only implemented when this is the case.) - raise NotImplementedError("domain and valuation.domain() must be the same rational function field but %r is not %r" % (domain, valuation.domain())) - else: - if domain.base() is not valuation.domain().base(): - raise NotImplementedError("domain and valuation.domain() must have the same base field but %r is not %r" % (domain.base(), valuation.domain().base())) - if to_valuation_domain != domain.hom([to_valuation_domain(domain.gen())]): - raise NotImplementedError("to_valuation_domain must be trivial on the base fields but %r is not %r" % (to_valuation_domain, domain.hom([to_valuation_domain(domain.gen())]))) - if from_valuation_domain != valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]): - raise NotImplementedError("from_valuation_domain must be trivial on the base fields but %r is not %r" % (from_valuation_domain, valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]))) - if to_valuation_domain(domain.gen()) == valuation.domain().gen(): - raise NotImplementedError("to_valuation_domain seems to be trivial but trivial maps would currently break partial orders of valuations") - - if from_valuation_domain(to_valuation_domain(domain.gen())) != domain.gen(): - # only a necessary condition - raise ValueError("to_valuation_domain and from_valuation_domain are not inverses of each other") - - return (domain, (valuation, to_valuation_domain, from_valuation_domain)), {} - - def create_object(self, version, key, **extra_args): - r""" - Create the valuation specified by ``key``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: w = valuations.GaussValuation(R, QQ.valuation(2)) - sage: v = K.valuation(w); v # indirect doctest - 2-adic valuation - - """ - domain, valuation = key - from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace - parent = DiscretePseudoValuationSpace(domain) - - if isinstance(valuation, tuple) and len(valuation) == 3: - valuation, to_valuation_domain, from_valuation_domain = valuation - if domain is domain.base() and valuation.domain() is valuation.domain().base(): - if valuation == valuation.domain().valuation(valuation.domain().gen()): - if to_valuation_domain != domain.hom([~valuation.domain().gen()]) or from_valuation_domain != valuation.domain().hom([~domain.gen()]): - raise ValueError("the only allowed automorphism for classical valuations is the automorphism x |--> 1/x") - # valuation on the rational function field after x |--> 1/x, - # i.e., the classical valuation at infinity - return parent.__make_element_class__(InfiniteRationalFunctionFieldValuation)(parent) - - from sage.structure.dynamic_class import dynamic_class - clazz = RationalFunctionFieldMappedValuation - if valuation.is_discrete_valuation(): - clazz = dynamic_class("RationalFunctionFieldMappedValuation_discrete", (clazz, DiscreteValuation)) - else: - clazz = dynamic_class("RationalFunctionFieldMappedValuation_infinite", (clazz, InfiniteDiscretePseudoValuation)) - return parent.__make_element_class__(clazz)(parent, valuation, to_valuation_domain, from_valuation_domain) - return parent.__make_element_class__(FunctionFieldExtensionMappedValuation)(parent, valuation, to_valuation_domain, from_valuation_domain) - - if domain is valuation.domain(): - # we cannot just return valuation in this case - # as this would break uniqueness and pickling - raise ValueError("valuation must not be a valuation on domain yet but %r is a valuation on %r" % (valuation, domain)) - - if domain.base_field() is domain: - # valuation is a base valuation on K[x] that induces a valuation on K(x) - if valuation.restriction(domain.constant_base_field()).is_trivial() and valuation.is_discrete_valuation(): - # valuation corresponds to a finite place - return parent.__make_element_class__(FiniteRationalFunctionFieldValuation)(parent, valuation) - else: - from sage.structure.dynamic_class import dynamic_class - clazz = NonClassicalRationalFunctionFieldValuation - if valuation.is_discrete_valuation(): - clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_discrete", (clazz, DiscreteFunctionFieldValuation_base)) - else: - clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_negative_infinite", (clazz, NegativeInfiniteDiscretePseudoValuation)) - return parent.__make_element_class__(clazz)(parent, valuation) - else: - # valuation is a limit valuation that singles out an extension - return parent.__make_element_class__(FunctionFieldFromLimitValuation)(parent, valuation, domain.polynomial(), extra_args['approximants']) - - raise NotImplementedError("valuation on %r from %r on %r" % (domain, valuation, valuation.domain())) - -FunctionFieldValuation = FunctionFieldValuationFactory("sage.rings.function_field.function_field_valuation.FunctionFieldValuation") - - -class FunctionFieldValuation_base(DiscretePseudoValuation): - r""" - Abstract base class for any discrete (pseudo-)valuation on a function - field. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest - sage: from sage.rings.function_field.function_field_valuation import FunctionFieldValuation_base - sage: isinstance(v, FunctionFieldValuation_base) - True - - """ - - -class DiscreteFunctionFieldValuation_base(DiscreteValuation): - r""" - Base class for discrete valuations on function fields. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest - sage: from sage.rings.function_field.function_field_valuation import DiscreteFunctionFieldValuation_base - sage: isinstance(v, DiscreteFunctionFieldValuation_base) - True - - """ - def extensions(self, L): - r""" - Return the extensions of this valuation to ``L``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) - sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular - [(x)-adic valuation] - - TESTS: - - Valuations over the infinite place:: - - sage: v = K.valuation(1/x) - sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular - sage: sorted(v.extensions(L), key=str) # optional - sage.libs.singular - [[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation, - [ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation] - - Iterated extensions over the infinite place:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari - Traceback (most recent call last): - ... - NotImplementedError - - A case that caused some trouble at some point:: - - sage: R. = QQ[] - sage: v = GaussValuation(R, QQ.valuation(2)) - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(v) - - sage: R. = K[] - sage: L. = K.extension(y^3 - x^4 - 1) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular - [2-adic valuation] - - Test that this works in towers:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: L. = L.extension(z - y) # optional - sage.libs.pari - sage: v = K.valuation(x) # optional - sage.libs.pari - sage: v.extensions(L) # optional - sage.libs.pari - [(x)-adic valuation] - """ - K = self.domain() - from sage.categories.function_fields import FunctionFields - if L is K: - return [self] - if L in FunctionFields(): - if K.is_subring(L): - if L.base() is K: - # L = K[y]/(G) is a simple extension of the domain of this valuation - G = L.polynomial() - if not G.is_monic(): - G = G / G.leading_coefficient() - if any(self(c) < 0 for c in G.coefficients()): - # rewrite L = K[u]/(H) with H integral and compute the extensions - from sage.rings.valuation.gauss_valuation import GaussValuation - g = GaussValuation(G.parent(), self) - y_to_u, u_to_y, H = g.monic_integral_model(G) - M = K.extension(H, names=L.variable_names()) - H_extensions = self.extensions(M) - - from sage.rings.morphism import RingHomomorphism_im_gens - if type(y_to_u) == RingHomomorphism_im_gens and type(u_to_y) == RingHomomorphism_im_gens: - return [L.valuation((w, L.hom([M(y_to_u(y_to_u.domain().gen()))]), M.hom([L(u_to_y(u_to_y.domain().gen()))]))) for w in H_extensions] - raise NotImplementedError - return [L.valuation(w) for w in self.mac_lane_approximants(L.polynomial(), require_incomparability=True)] - elif L.base() is not L and K.is_subring(L): - # recursively call this method for the tower of fields - from operator import add - from functools import reduce - A = [base_valuation.extensions(L) for base_valuation in self.extensions(L.base())] - return reduce(add, A, []) - elif L.constant_base_field() is not K.constant_base_field() and K.constant_base_field().is_subring(L): - # subclasses should override this method and handle this case, so we never get here - raise NotImplementedError("Cannot compute the extensions of %r from %r to %r since the base ring changes." % (self, self.domain(), L)) - raise NotImplementedError("extension of %r from %r to %r not implemented" % (self, K, L)) - - -class RationalFunctionFieldValuation_base(FunctionFieldValuation_base): - r""" - Base class for valuations on rational function fields. - - TESTS:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari - sage: from sage.rings.function_field.function_field_valuation import RationalFunctionFieldValuation_base - sage: isinstance(v, RationalFunctionFieldValuation_base) # optional - sage.libs.pari - True - - """ - @cached_method - def element_with_valuation(self, s): - r""" - Return an element with valuation ``s``. - - EXAMPLES:: - - sage: K. = NumberField(x^3+6) # optional - sage.rings.number_field - sage: v = K.valuation(2) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: w = GaussValuation(R, v).augmentation(x, 1/123) # optional - sage.rings.number_field - sage: K. = FunctionField(K) # optional - sage.rings.number_field - sage: w = w.extension(K) # optional - sage.rings.number_field - sage: w.element_with_valuation(122/123) # optional - sage.rings.number_field - 2/x - sage: w.element_with_valuation(1) # optional - sage.rings.number_field - 2 - - """ - constant_valuation = self.restriction(self.domain().constant_base_field()) - if constant_valuation.is_trivial(): - return super().element_with_valuation(s) - - a, b = self.value_group()._element_with_valuation(constant_valuation.value_group(), s) - ret = self.uniformizer()**a * constant_valuation.element_with_valuation(constant_valuation.value_group().gen()*b) - - return self.simplify(ret, error=s) - - -class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base): - r""" - Base class for discrete valuations on rational function fields that come - from points on the projective line. - - TESTS:: - - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari - sage: from sage.rings.function_field.function_field_valuation import ClassicalFunctionFieldValuation_base - sage: isinstance(v, ClassicalFunctionFieldValuation_base) # optional - sage.libs.pari - True - - """ - def _test_classical_residue_field(self, **options): - r""" - Check correctness of the residue field of a discrete valuation at a - classical point. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) - sage: v._test_classical_residue_field() - - """ - tester = self._tester(**options) - - tester.assertTrue(self.domain().constant_base_field().is_subring(self.residue_field())) - - def _ge_(self, other): - r""" - Return whether ``self`` is greater or equal to ``other`` everywhere. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) - sage: w = K.valuation(x) - sage: v >= w - False - sage: w >= v - False - - """ - if other.is_trivial(): - return other.is_discrete_valuation() - if isinstance(other, ClassicalFunctionFieldValuation_base): - return self == other - super()._ge_(other) - - -class InducedRationalFunctionFieldValuation_base(FunctionFieldValuation_base): - r""" - Base class for function field valuation induced by a valuation on the - underlying polynomial ring. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) # indirect doctest - - """ - def __init__(self, parent, base_valuation): - r""" - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest - sage: from sage.rings.function_field.function_field_valuation import InducedRationalFunctionFieldValuation_base - sage: isinstance(v, InducedRationalFunctionFieldValuation_base) - True - - """ - FunctionFieldValuation_base.__init__(self, parent) - - domain = parent.domain() - if base_valuation.domain() is not domain._ring: - raise ValueError("base valuation must be defined on %r but %r is defined on %r" % (domain._ring, base_valuation, base_valuation.domain())) - - self._base_valuation = base_valuation - - def uniformizer(self): - r""" - Return a uniformizing element for this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(x).uniformizer() - x - - """ - return self.domain()(self._base_valuation.uniformizer()) - - def lift(self, F): - r""" - Return a lift of ``F`` to the domain of this valuation such - that :meth:`reduce` returns the original element. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) - sage: v.lift(0) - 0 - sage: v.lift(1) - 1 - - """ - F = self.residue_ring().coerce(F) - if F in self._base_valuation.residue_ring(): - num = self._base_valuation.residue_ring()(F) - den = self._base_valuation.residue_ring()(1) - elif F in self._base_valuation.residue_ring().fraction_field(): - num = self._base_valuation.residue_ring()(F.numerator()) - den = self._base_valuation.residue_ring()(F.denominator()) - else: - raise NotImplementedError("lifting not implemented for this valuation") - - return self.domain()(self._base_valuation.lift(num)) / self.domain()(self._base_valuation.lift(den)) - - def value_group(self): - r""" - Return the value group of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(x).value_group() - Additive Abelian Group generated by 1 - - """ - return self._base_valuation.value_group() - - def reduce(self, f): - r""" - Return the reduction of ``f`` in :meth:`residue_ring`. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) - sage: v.reduce(x) - u1 - - """ - f = self.domain().coerce(f) - - if self(f) > 0: - return self.residue_field().zero() - if self(f) < 0: - raise ValueError("cannot reduce element of negative valuation") - - base = self._base_valuation - - num = f.numerator() - den = f.denominator() - - assert base(num) == base(den) - shift = base.element_with_valuation(-base(num)) - num *= shift - den *= shift - ret = base.reduce(num) / base.reduce(den) - assert not ret.is_zero() - return self.residue_field()(ret) - - def _repr_(self): - r""" - Return a printable representation of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(x^2 + 1) # indirect doctest - (x^2 + 1)-adic valuation - - """ - from sage.rings.valuation.augmented_valuation import AugmentedValuation_base - from sage.rings.valuation.gauss_valuation import GaussValuation - if isinstance(self._base_valuation, AugmentedValuation_base): - if self._base_valuation._base_valuation == GaussValuation(self.domain()._ring, TrivialValuation(self.domain().constant_base_field())): - if self._base_valuation._mu == 1: - return "(%r)-adic valuation" % (self._base_valuation.phi()) - vK = self._base_valuation.restriction(self._base_valuation.domain().base_ring()) - if self._base_valuation == GaussValuation(self.domain()._ring, vK): - return repr(vK) - return "Valuation on rational function field induced by %s" % self._base_valuation - - def extensions(self, L): - r""" - Return all extensions of this valuation to ``L`` which has a larger - constant field than the domain of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x^2 + 1) - sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: v.extensions(L) # indirect doctest - [(x - I)-adic valuation, (x + I)-adic valuation] - - """ - K = self.domain() - if L is K: - return [self] - - from sage.categories.function_fields import FunctionFields - if (L in FunctionFields() - and K.is_subring(L) - and L.base() is L - and L.constant_base_field() is not K.constant_base_field() - and K.constant_base_field().is_subring(L.constant_base_field())): - # The above condition checks whether L is an extension of K that - # comes from an extension of the field of constants - # Condition "L.base() is L" is important so we do not call this - # code for extensions from K(x) to K(x)(y) - - # We extend the underlying valuation on the polynomial ring - W = self._base_valuation.extensions(L._ring) - return [L.valuation(w) for w in W] - - return super().extensions(L) - - def _call_(self, f): - r""" - Evaluate this valuation at the function ``f``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest - sage: v((x+1)/x^2) - -2 - - """ - return self._base_valuation(f.numerator()) - self._base_valuation(f.denominator()) - - def residue_ring(self): - r""" - Return the residue field of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(x).residue_ring() - Rational Field - - """ - return self._base_valuation.residue_ring().fraction_field() - - def restriction(self, ring): - r""" - Return the restriction of this valuation to ``ring``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(x).restriction(QQ) - Trivial valuation on Rational Field - - """ - if ring.is_subring(self._base_valuation.domain()): - return self._base_valuation.restriction(ring) - return super().restriction(ring) - - def simplify(self, f, error=None, force=False): - r""" - Return a simplified version of ``f``. - - Produce an element which differs from ``f`` by an element of - valuation strictly greater than the valuation of ``f`` (or strictly - greater than ``error`` if set.) - - If ``force`` is not set, then expensive simplifications may be avoided. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(2) - sage: f = (x + 1)/(x - 1) - - As the coefficients of this fraction are small, we do not simplify as - this could be very costly in some cases:: - - sage: v.simplify(f) - (x + 1)/(x - 1) - - However, simplification can be forced:: - - sage: v.simplify(f, force=True) - 3 - - """ - f = self.domain().coerce(f) - - if error is None: - # if the caller was sure that we should simplify, then we should try to do the best simplification possible - error = self(f) if force else self.upper_bound(f) - - from sage.rings.infinity import infinity - if error is infinity: - return f - - numerator = f.numerator() - denominator = f.denominator() - - v_numerator = self._base_valuation(numerator) - v_denominator = self._base_valuation(denominator) - - if v_numerator - v_denominator > error: - return self.domain().zero() - - if error == -infinity: - # This case is not implemented yet, so we just return f which is always safe. - return f - - numerator = self.domain()(self._base_valuation.simplify(numerator, error=error+v_denominator, force=force)) - denominator = self.domain()(self._base_valuation.simplify(denominator, error=max(v_denominator, error - v_numerator + 2*v_denominator), force=force)) - - ret = numerator/denominator - assert self(ret - f) > error - return ret - - def _relative_size(self, f): - r""" - Return an estimate on the coefficient size of ``f``. - - The number returned is an estimate on the factor between the number of - bits used by ``f`` and the minimal number of bits used by an element - congruent to ``f``. - - This can be used by :meth:`simplify` to decide whether simplification - of coefficients is going to lead to a significant shrinking of the - coefficients of ``f``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(0) - sage: f = (x + 1024)/(x - 1024) - - Here we report a small size, as the numerator and the denominator - independently cannot be simplified much:: - - sage: v._relative_size(f) - 1 - - However, a forced simplification, finds that we could have saved many - more bits:: - - sage: v.simplify(f, force=True) - -1 - - """ - return max(self._base_valuation._relative_size(f.numerator()), self._base_valuation._relative_size(f.denominator())) - - -class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base, RationalFunctionFieldValuation_base): - r""" - Valuation of a finite place of a function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x + 1); v # indirect doctest - (x + 1)-adic valuation - - A finite place with residual degree:: - - sage: w = K.valuation(x^2 + 1); w - (x^2 + 1)-adic valuation - - A finite place with ramification:: - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: L. = FunctionField(K) # optional - sage.libs.pari - sage: u = L.valuation(x^3 - t); u # optional - sage.libs.pari - (x^3 + 2*t)-adic valuation - - A finite place with residual degree and ramification:: - - sage: q = L.valuation(x^6 - t); q # optional - sage.libs.pari - (x^6 + 2*t)-adic valuation - - """ - def __init__(self, parent, base_valuation): - r""" - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(x + 1) - sage: from sage.rings.function_field.function_field_valuation import FiniteRationalFunctionFieldValuation - sage: isinstance(v, FiniteRationalFunctionFieldValuation) - True - - """ - InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) - ClassicalFunctionFieldValuation_base.__init__(self, parent) - RationalFunctionFieldValuation_base.__init__(self, parent) - - -class NonClassicalRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, RationalFunctionFieldValuation_base): - r""" - Valuation induced by a valuation on the underlying polynomial ring which is - non-classical. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = GaussValuation(QQ['x'], QQ.valuation(2)) - sage: w = K.valuation(v); w # indirect doctest - 2-adic valuation - - """ - def __init__(self, parent, base_valuation): - r""" - TESTS: - - There is some support for discrete pseudo-valuations on rational - function fields in the code. However, since these valuations must send - elements to `-\infty`, they are not supported yet:: - - sage: R. = QQ[] - sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity) - sage: K. = FunctionField(QQ) - sage: w = K.valuation(v) - sage: from sage.rings.function_field.function_field_valuation import NonClassicalRationalFunctionFieldValuation - sage: isinstance(w, NonClassicalRationalFunctionFieldValuation) - True - - """ - InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) - RationalFunctionFieldValuation_base.__init__(self, parent) - - def residue_ring(self): - r""" - Return the residue field of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = valuations.GaussValuation(QQ['x'], QQ.valuation(2)) - sage: w = K.valuation(v) - sage: w.residue_ring() - Rational function field in x over Finite Field of size 2 - - sage: R. = QQ[] - sage: vv = v.augmentation(x, 1) - sage: w = K.valuation(vv) - sage: w.residue_ring() - Rational function field in x over Finite Field of size 2 - - sage: R. = K[] - sage: L. = K.extension(y^2 + 2*x) # optional - sage.libs.singular - sage: w.extension(L).residue_ring() # optional - sage.libs.singular - Function field in u2 defined by u2^2 + x - - TESTS: - - This still works for pseudo-valuations:: - - sage: R. = QQ[] - sage: v = valuations.GaussValuation(R, QQ.valuation(2)) - sage: vv = v.augmentation(x, infinity) - sage: K. = FunctionField(QQ) - sage: w = K.valuation(vv) - sage: w.residue_ring() - Finite Field of size 2 - - """ - if not self.is_discrete_valuation(): - # A pseudo valuation attaining negative infinity does typically not have a function field as its residue ring - return super().residue_ring() - return self._base_valuation.residue_ring().fraction_field().function_field() - - -class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, DiscreteFunctionFieldValuation_base): - r""" - A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is - another function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L); w # optional - sage.libs.singular - (x - 1)-adic valuation - - """ - def __init__(self, parent, approximant, G, approximants): - r""" - TESTS:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular - sage: from sage.rings.function_field.function_field_valuation import FunctionFieldFromLimitValuation - sage: isinstance(w, FunctionFieldFromLimitValuation) # optional - sage.libs.singular - True - - """ - FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants) - DiscreteFunctionFieldValuation_base.__init__(self, parent) - - def _to_base_domain(self, f): - r""" - Return ``f`` as an element of the domain of the underlying limit valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular - sage: w._to_base_domain(y).parent() # optional - sage.libs.singular - Univariate Polynomial Ring in y over Rational function field in x over Rational Field - - """ - return f.element() - - def scale(self, scalar): - r""" - Return this valuation scaled by ``scalar``. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular - sage: 3*w # optional - sage.libs.singular - 3 * (x - 1)-adic valuation - - """ - if scalar in QQ and scalar > 0 and scalar != 1: - return self.domain().valuation(self._base_valuation._initial_approximation.scale(scalar)) - return super().scale(scalar) - - -class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValuation_base): - r""" - A valuation on a function field which relies on a ``base_valuation`` on an - isomorphic function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x); v # optional - sage.libs.pari - Valuation at the infinite place - - """ - def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): - r""" - TESTS:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: from sage.rings.function_field.function_field_valuation import FunctionFieldMappedValuation_base - sage: isinstance(v, FunctionFieldMappedValuation_base) # optional - sage.libs.pari - True - - """ - FunctionFieldValuation_base.__init__(self, parent) - MappedValuation_base.__init__(self, parent, base_valuation) - - self._to_base = to_base_valuation_domain - self._from_base = from_base_valuation_domain - - def _to_base_domain(self, f): - r""" - Return ``f`` as an element in the domain of ``_base_valuation``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w._to_base_domain(y) # optional - sage.libs.pari - x^2*y - - """ - return self._to_base(f) - - def _from_base_domain(self, f): - r""" - Return ``f`` as an element in the domain of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari - y - - r""" - return self._from_base(f) - - def scale(self, scalar): - r""" - Return this valuation scaled by ``scalar``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: 3*w # optional - sage.libs.pari - 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) - - """ - from sage.rings.rational_field import QQ - if scalar in QQ and scalar > 0 and scalar != 1: - return self.domain().valuation((self._base_valuation.scale(scalar), self._to_base, self._from_base)) - return super().scale(scalar) - - def _repr_(self): - r""" - Return a printable representation of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: v.extension(L) # indirect doctest # optional - sage.libs.pari - Valuation at the infinite place - - """ - to_base = repr(self._to_base) - if hasattr(self._to_base, '_repr_defn'): - to_base = self._to_base._repr_defn().replace('\n', ', ') - return "%r (in %r after %s)" % (self._base_valuation, self._base_valuation.domain(), to_base) - - def is_discrete_valuation(self): - r""" - Return whether this is a discrete valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - x^4 - 1) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w0,w1 = v.extensions(L) # optional - sage.libs.pari - sage: w0.is_discrete_valuation() # optional - sage.libs.pari - True - - """ - return self._base_valuation.is_discrete_valuation() - - -class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_base): - r""" - A valuation on a function field which relies on a ``base_valuation`` on an - isomorphic function field and which is such that the map from and to the - other function field is the identity on the constant field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x); v # optional - sage.libs.pari - Valuation at the infinite place - - """ - def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): - r""" - TESTS:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: from sage.rings.function_field.function_field_valuation import FunctionFieldMappedValuationRelative_base - sage: isinstance(v, FunctionFieldMappedValuationRelative_base) # optional - sage.libs.pari - True - - """ - FunctionFieldMappedValuation_base.__init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain) - if self.domain().constant_base_field() is not base_valuation.domain().constant_base_field(): - raise ValueError("constant fields must be identical but they differ for %r and %r" % (self.domain(), base_valuation.domain())) - - def restriction(self, ring): - r""" - Return the restriction of this valuation to ``ring``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: K.valuation(1/x).restriction(GF(2)) # optional - sage.libs.pari - Trivial valuation on Finite Field of size 2 - - """ - if ring.is_subring(self.domain().constant_base_field()): - return self._base_valuation.restriction(ring) - return super().restriction(ring) - - -class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base): - r""" - Valuation on a rational function field that is implemented after a map to - an isomorphic rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) - sage: w = K.valuation(w) - sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v - Valuation on rational function field induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] (in Rational function field in x over Rational Field after x |--> 1/x) - - """ - def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain): - r""" - TESTS:: - - sage: K. = FunctionField(QQ) - sage: R. = QQ[] - sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) - sage: w = K.valuation(w) - sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) - sage: from sage.rings.function_field.function_field_valuation import RationalFunctionFieldMappedValuation - sage: isinstance(v, RationalFunctionFieldMappedValuation) - True - - """ - FunctionFieldMappedValuationRelative_base.__init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain) - RationalFunctionFieldValuation_base.__init__(self, parent) - - -class InfiniteRationalFunctionFieldValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base): - r""" - Valuation of the infinite place of a function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1/x) # indirect doctest - - """ - def __init__(self, parent): - r""" - TESTS:: - - sage: K. = FunctionField(QQ) - sage: v = K.valuation(1/x) # indirect doctest - sage: from sage.rings.function_field.function_field_valuation import InfiniteRationalFunctionFieldValuation - sage: isinstance(v, InfiniteRationalFunctionFieldValuation) - True - - """ - x = parent.domain().gen() - FunctionFieldMappedValuationRelative_base.__init__(self, parent, FunctionFieldValuation(parent.domain(), x), parent.domain().hom([1/x]), parent.domain().hom([1/x])) - RationalFunctionFieldValuation_base.__init__(self, parent) - ClassicalFunctionFieldValuation_base.__init__(self, parent) - - def _repr_(self): - r""" - Return a printable representation of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: K.valuation(1/x) # indirect doctest - Valuation at the infinite place - - """ - return "Valuation at the infinite place" - - -class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative_base): - r""" - A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is - another function field which redirects to another ``base_valuation`` on an - isomorphism function field `M=K[y]/(H)`. - - The isomorphisms must be trivial on ``K``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - - sage: w(x) # optional - sage.libs.pari - -1 - sage: w(y) # optional - sage.libs.pari - -3/2 - sage: w.uniformizer() # optional - sage.libs.pari - 1/x^2*y - - TESTS:: - - sage: from sage.rings.function_field.function_field_valuation import FunctionFieldExtensionMappedValuation - sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari - True - - """ - def _repr_(self): - r""" - Return a printable representation of this valuation. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L); w # optional - sage.libs.pari - Valuation at the infinite place - - sage: K. = FunctionField(QQ) - sage: R. = K[] - sage: L. = K.extension(y^2 - 1/x^2 - 1) # optional - sage.libs.singular - sage: v = K.valuation(1/x) # optional - sage.libs.singular - sage: w = v.extensions(L); w # optional - sage.libs.singular - [[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation, - [ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation] - - """ - assert(self.domain().base() is not self.domain()) - if repr(self._base_valuation) == repr(self.restriction(self.domain().base())): - return repr(self._base_valuation) - return super()._repr_() - - def restriction(self, ring): - r""" - Return the restriction of this valuation to ``ring``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w.restriction(K) is v # optional - sage.libs.pari - True - """ - if ring.is_subring(self.domain().base()): - return self._base_valuation.restriction(ring) - return super().restriction(ring) diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index dd375fe79cd..6401ecbd581 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -77,6 +77,7 @@ - Kwankyu Lee (2017-04-30): added ideals for global function fields """ + # **************************************************************************** # Copyright (C) 2010 William Stein # Copyright (C) 2011 Maarten Derickx @@ -86,24 +87,15 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -import itertools -from sage.misc.cachefunc import cached_method -from sage.misc.lazy_attribute import lazy_attribute from sage.misc.latex import latex from sage.misc.misc import powerset - from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.richcmp import richcmp from sage.structure.factorization import Factorization from sage.structure.unique_representation import UniqueRepresentation - -from sage.arith.power import generic_power - from sage.categories.monoids import Monoids - -from sage.rings.infinity import infinity from sage.rings.ideal import Ideal_generic @@ -554,329 +546,6 @@ def divisor_of_poles(self): return divisor(F, data) -class FunctionFieldIdeal_rational(FunctionFieldIdeal): - """ - Fractional ideals of the maximal order of a rational function field. - - INPUT: - - - ``ring`` -- the maximal order of the rational function field. - - - ``gen`` -- generator of the ideal, an element of the function field. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(1/(x^2+x)); I - Ideal (1/(x^2 + x)) of Maximal order of Rational function field in x over Rational Field - """ - def __init__(self, ring, gen): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(1/(x^2+x)) - sage: TestSuite(I).run() - """ - FunctionFieldIdeal.__init__(self, ring) - self._gen = gen - - def __hash__(self): - """ - Return the hash computed from the data. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(1/(x^2+x)) - sage: d = { I: 1, I^2: 2 } - """ - return hash( (self._ring, self._gen) ) - - def __contains__(self, element): - """ - Test if ``element`` is in this ideal. - - INPUT: - - - ``element`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(1/(x+1)) - sage: x in I - True - """ - return (element / self._gen) in self._ring - - def _richcmp_(self, other, op): - """ - Compare the element with the other element with respect - to the comparison operator. - - INPUT: - - - ``other`` -- element - - - ``op`` -- comparison operator - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+1) - sage: J = O.ideal(x^2+x+1,x) - sage: I == J - True - sage: I = O.ideal(x) - sage: J = O.ideal(x+1) - sage: I < J - True - """ - return richcmp(self._gen, other._gen, op) - - def _add_(self, other): - """ - Add this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+1) - sage: J = O.ideal(x^2+x+1,x) - sage: I + J == J + I - True - """ - return self._ring.ideal([self._gen, other._gen]) - - def _mul_(self, other): - """ - Multiply this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+x) - sage: J = O.ideal(x^2,x) - sage: I * J == J * I - True - """ - return self._ring.ideal([self._gen * other._gen]) - - def _acted_upon_(self, other, on_left): - """ - Multiply ``other`` with this ideal on the right. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x^3+x^2) - sage: 2 * I - Ideal (x^3 + x^2) of Maximal order of Rational function field in x over Rational Field - sage: x * I - Ideal (x^4 + x^3) of Maximal order of Rational function field in x over Rational Field - """ - return self._ring.ideal([other * self._gen]) - - def __invert__(self): - """ - Return the ideal inverse of this fractional ideal. - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: I = O.ideal(x/(x^2+1)) - sage: ~I - Ideal ((x^2 + 1)/x) of Maximal order of Rational function field - in x over Rational Field - """ - return self._ring.ideal([~(self._gen)]) - - def denominator(self): - """ - Return the denominator of this fractional ideal. - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: I = O.ideal(x/(x^2+1)) - sage: I.denominator() - x^2 + 1 - """ - return self._gen.denominator() - - def is_prime(self): - """ - Return ``True`` if this is a prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x^3 + x^2) - sage: [f.is_prime() for f,m in I.factor()] # optional - sage.libs.pari - [True, True] - """ - return self._gen.denominator() == 1 and self._gen.numerator().is_prime() - - @cached_method - def module(self): - """ - Return the module, that is the ideal viewed as a module over the ring. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order() - sage: I = O.ideal(x^3+x^2) - sage: I.module() # optional - sage.modules - Free module of degree 1 and rank 1 over Maximal order of Rational - function field in x over Rational Field - Echelon basis matrix: - [x^3 + x^2] - sage: J = 0*I - sage: J.module() # optional - sage.modules - Free module of degree 1 and rank 0 over Maximal order of Rational - function field in x over Rational Field - Echelon basis matrix: - [] - """ - V, fr, to = self.ring().fraction_field().vector_space() - return V.span([to(g) for g in self.gens()], base_ring=self.ring()) - - def gen(self): - """ - Return the unique generator of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari - sage: I.gen() # optional - sage.libs.pari - x^2 + x - """ - return self._gen - - def gens(self): - """ - Return the tuple of the unique generator of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^2 + x,) - """ - return (self._gen,) - - def gens_over_base(self): - """ - Return the generator of this ideal as a rank one module over the maximal - order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari - (x^2 + x,) - """ - return (self._gen,) - - def valuation(self, ideal): - """ - Return the valuation of the ideal at this prime ideal. - - INPUT: - - - ``ideal`` -- fractional ideal - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: I = O.ideal(x^2*(x^2+x+1)^3) - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari - [2, 3] - """ - if not self.is_prime(): - raise TypeError("not a prime ideal") - - O = self.ring() - d = ideal.denominator() - return self._valuation(d*ideal) - self._valuation(O.ideal(d)) - - def _valuation(self, ideal): - """ - Return the valuation of the integral ideal at this prime ideal. - - INPUT: - - - ``ideal`` -- ideal - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order() - sage: p = O.ideal(x) - sage: p.valuation(O.ideal(x+1)) # indirect doctest - 0 - sage: p.valuation(O.ideal(x^2)) # indirect doctest - 2 - sage: p.valuation(O.ideal(1/x^3)) # indirect doctest - -3 - sage: p.valuation(O.ideal(0)) # indirect doctest - +Infinity - """ - return ideal.gen().valuation(self.gen()) - - def _factor(self): - """ - Return the list of prime and multiplicity pairs of the - factorization of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3*(x+1)^2) # optional - sage.libs.pari - sage: I.factor() # indirect doctest # optional - sage.libs.pari - (Ideal (x) of Maximal order of Rational function field in x - over Finite Field in z2 of size 2^2)^3 * - (Ideal (x + 1) of Maximal order of Rational function field in x - over Finite Field in z2 of size 2^2)^2 - """ - return [(self.ring().ideal(f), m) for f, m in self._gen.factor()] - - class FunctionFieldIdeal_module(FunctionFieldIdeal, Ideal_generic): """ A fractional ideal specified by a finitely generated module over @@ -1168,2090 +837,150 @@ def __invert__(self): return inv -class FunctionFieldIdeal_polymod(FunctionFieldIdeal): +class FunctionFieldIdealInfinite(FunctionFieldIdeal): + """ + Base class of ideals of maximal infinite orders """ - Fractional ideals of algebraic function fields + pass - INPUT: - - ``ring`` -- order in a function field +class FunctionFieldIdealInfinite_module(FunctionFieldIdealInfinite, Ideal_generic): + """ + A fractional ideal specified by a finitely generated module over + the integers of the base field. - - ``hnf`` -- matrix in hermite normal form + INPUT: - - ``denominator`` -- denominator + - ``ring`` -- order in a function field - The rows of ``hnf`` is a basis of the ideal, which itself is - ``denominator`` times the fractional ideal. + - ``module`` -- module EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.ideal(y) # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.ideal(y) # optional - sage.libs.singular + Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ - def __init__(self, ring, hnf, denominator=1): + def __init__(self, ring, module): """ Initialize. TESTS:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: TestSuite(I).run() # optional - sage.libs.singular """ - FunctionFieldIdeal.__init__(self, ring) + FunctionFieldIdealInfinite.__init__(self, ring) - # the denominator and the entries of the hnf are - # univariate polynomials. - self._hnf = hnf - self._denominator = denominator + self._module = module + self._structure = ring.fraction_field().vector_space() - # for prime ideals - self._relative_degree = None - self._ramification_index = None - self._prime_below = None - self._beta = None + V, from_V, to_V = self._structure + gens = tuple([from_V(a) for a in module.basis()]) + self._gens = gens - # beta in matrix form for fast multiplication - self._beta_matrix = None + # module generators are still ideal generators + Ideal_generic.__init__(self, ring, self._gens, coerce=False) - # (p, q) with irreducible polynomial p and q an element of O in vector - # form, together generating the prime ideal. This data is obtained by - # Kummer's theorem when this prime ideal is constructed. This is used - # for fast multiplication with other ideal. - self._kummer_form = None + def __contains__(self, x): + """ + Return ``True`` if ``x`` is in this ideal. - # tuple of at most two gens: - # the first gen is an element of the base ring of the maximal order - # the second gen is the vector form of an element of the maximal order - # if the second gen is zero, the tuple has only the first gen. - self._gens_two_vecs = None + INPUT: - def __bool__(self): - """ - Test if this ideal is zero. + - ``x`` -- element of the function field EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: I.is_zero() # optional - sage.libs.pari - False - sage: J = 0*I; J # optional - sage.libs.pari - Zero ideal of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J.is_zero() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 + sage: y in I # optional - sage.libs.pari True - - sage: K.=FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari - sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - sage: I.is_zero() # optional - sage.libs.pari + sage: y/x in I # optional - sage.libs.pari False - sage: J = 0*I; J # optional - sage.libs.pari - Zero ideal of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: J.is_zero() # optional - sage.libs.pari + sage: y^2 - 2 in I # optional - sage.libs.pari True """ - return self._hnf.nrows() != 0 - - + return self._structure[2](x) in self._module def __hash__(self): """ - Return the hash of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: { I: 2 }[I] == 2 # optional - sage.libs.pari - True - - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: { I: 2 }[I] == 2 # optional - sage.libs.pari - True - """ - return hash((self._ring, self._hnf, self._denominator)) - - def __contains__(self, x): - """ - Return ``True`` if ``x`` is in this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal([y]); I # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y - defined by y^2 + 6*x^3 + 6 - sage: x * y in I # optional - sage.libs.pari - True - sage: y / x in I # optional - sage.libs.pari - False - sage: y^2 - 2 in I # optional - sage.libs.pari - False - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal([y]); I # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I # optional - sage.libs.pari - True - sage: y / x in I # optional - sage.libs.pari - False - sage: y^2 - 2 in I # optional - sage.libs.pari - False - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal([y]); I # optional - sage.libs.singular - Ideal (y) of Maximal order of Function field in y - defined by y^2 - x^3 - 1 - sage: x * y in I # optional - sage.libs.singular - True - sage: y / x in I # optional - sage.libs.singular - False - sage: y^2 - 2 in I # optional - sage.libs.singular - False - - sage: K. = FunctionField(QQ); _. = K[] # optional - sage.libs.singular - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal([y]); I # optional - sage.libs.singular - Ideal (y) of Maximal order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I # optional - sage.libs.singular - True - sage: y / x in I # optional - sage.libs.singular - False - sage: y^2 - 2 in I # optional - sage.libs.singular - False - """ - from sage.modules.free_module_element import vector - - vec = self.ring().coordinate_vector(self._denominator * x) - v = [] - for e in vec: - if e.denominator() != 1: - return False - v.append(e.numerator()) - vec = vector(v) - return vec in self._hnf.image() - - def __invert__(self): - """ - Return the inverse fractional ideal of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: ~I # optional - sage.libs.pari - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I^(-1) # optional - sage.libs.pari - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: ~I * I # optional - sage.libs.pari - Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - - :: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: ~I # optional - sage.libs.pari - Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) # optional - sage.libs.pari - Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I # optional - sage.libs.pari - Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - - :: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: ~I # optional - sage.libs.singular - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I^(-1) # optional - sage.libs.singular - Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: ~I * I # optional - sage.libs.singular - Ideal (1) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - - :: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: ~I # optional - sage.libs.singular - Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) # optional - sage.libs.singular - Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I # optional - sage.libs.singular - Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - R = self.ring() - T = R._codifferent_matrix() - I = self * R.codifferent() - J = I._denominator * (I._hnf * T).inverse() - return R._ideal_from_vectors(J.columns()) - - def _richcmp_(self, other, op): - """ - Compare this ideal with the other ideal with respect to ``op``. - - INPUT: - - - ``other`` -- ideal - - - ``op`` -- comparison operator - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I == I + I # optional - sage.libs.pari - True - sage: I == I * I # optional - sage.libs.pari - False - - :: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I == I + I # optional - sage.libs.pari - True - sage: I == I * I # optional - sage.libs.pari - False - sage: I < I * I # optional - sage.libs.pari - True - sage: I > I * I # optional - sage.libs.pari - False - """ - return richcmp((self._denominator, self._hnf), (other._denominator, other._hnf), op) - - def _add_(self, other): - """ - Add with other ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari - Ideal (1, y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - ds = self._denominator - do = other._denominator - vecs1 = [do * r for r in self._hnf] - vecs2 = [ds * r for r in other._hnf] - return self._ring._ideal_from_vectors_and_denominator(vecs1 + vecs2, ds * do) - - def _mul_(self, other): - """ - Multiply with other ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari - Ideal (x^4 + x^2 + x, x*y + x^2) of Maximal order - of Function field in y defined by y^2 + x^3*y + x - - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari - Ideal ((x + 1)*y + (x^2 + 1)/x) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - O = self._ring - mul = O._mul_vecs - - if self._kummer_form is not None: - p, q = self._kummer_form - vecs = list(p * other._hnf) + [mul(q, v) for v in other._hnf] - elif other._kummer_form is not None: - p, q = other._kummer_form - vecs = list(p * self._hnf) + [mul(q, v) for v in self._hnf] - elif self._gens_two_vecs is not None: - if len(self._gens_two_vecs) == 1: - g1, = self._gens_two_vecs - vecs = list(g1 * other._hnf) - else: - g1, g2 = self._gens_two_vecs - vecs = list(g1 * other._hnf) + [mul(g2, v) for v in other._hnf] - elif other._gens_two_vecs is not None: - if len(other._gens_two_vecs) == 1: - g1, = other._gens_two_vecs - vecs = list(g1 * self._hnf) - else: - g1, g2 = other._gens_two_vecs - vecs = list(g1 * self._hnf) + [mul(g2, v) for v in self._hnf] - else: - vecs = [mul(r1,r2) for r1 in self._hnf for r2 in other._hnf] - - return O._ideal_from_vectors_and_denominator(vecs, self._denominator * other._denominator) - - def _acted_upon_(self, other, on_left): - """ - Multiply ``other`` and this ideal on the right. + Return the hash of this ideal EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: x * I == I * J # optional - sage.libs.pari - True - - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: x * I == I * J # optional - sage.libs.pari - True + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari + sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari """ - from sage.modules.free_module_element import vector - - O = self._ring - mul = O._mul_vecs - - # compute the vector form of other element - v = O.coordinate_vector(other) - d = v.denominator() - vec = vector([(d * c).numerator() for c in v]) - - # multiply with the ideal - vecs = [mul(vec, r) for r in self._hnf] - - return O._ideal_from_vectors_and_denominator(vecs, d * self._denominator) + return hash((self._ring,self._module)) - def intersect(self, other): + def __eq__(self, other): """ - Intersect this ideal with the other ideal as fractional ideals. + Test equality of this ideal with the ``other`` ideal. INPUT: - ``other`` -- ideal - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.libs.pari - True - - """ - from sage.matrix.special import block_matrix - from .hermite_form_polynomial import reversed_hermite_form - - A = self._hnf - B = other._hnf - - ds = self.denominator() - do = other.denominator() - d = ds.lcm(do) - if not d.is_one(): - A = (d // ds) * A - B = (d // do) * B - - MS = A.matrix_space() - I = MS.identity_matrix() - O = MS.zero() - n = A.ncols() - - # intersect the row spaces of A and B - M = block_matrix([[I,I],[A,O],[O,B]]) - - # reversed Hermite form - U = reversed_hermite_form(M, transformation=True) - - vecs = [U[i][:n] for i in range(n)] - - return self._ring._ideal_from_vectors_and_denominator(vecs, d) - - def hnf(self): - """ - Return the matrix in hermite normal form representing this ideal. - - See also :meth:`denominator` - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.pari - [x^6 + x^3 0] - [ x^3 + 1 1] - - :: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.singular - [x^6 + x^3 0] - [ x^3 + 1 1] - """ - return self._hnf - - def denominator(self): - """ - Return the denominator of this fractional ideal. - EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y/(y+1)) # optional - sage.libs.pari - sage: d = I.denominator(); d # optional - sage.libs.pari - x^3 - sage: d in O # optional - sage.libs.pari - True - - :: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y/(y+1)) # optional - sage.libs.singular - sage: d = I.denominator(); d # optional - sage.libs.singular - x^3 - sage: d in O # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari + sage: I == I + I # indirect doctest # optional - sage.libs.pari True """ - return self._denominator + if not isinstance(other, FunctionFieldIdeal_module): + other = self.ring().ideal(other) + if self.ring() != other.ring(): + raise ValueError("rings must be the same") + + if (self.module().is_submodule(other.module()) and + other.module().is_submodule(self.module())): + return True + else: + return False - @cached_method def module(self): """ - Return the module, that is the ideal viewed as a module - over the base maximal order. + Return the module over the maximal order of the base field that + underlies this ideal. + + The formation of the module is compatible with the vector + space corresponding to the function field. EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: O = K.maximal_order(); O # optional - sage.libs.pari + Maximal order of Rational function field in x over Finite Field of size 7 + sage: K.polynomial_ring() # optional - sage.libs.pari + Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7 + sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^2 + 1,) sage: I.module() # optional - sage.libs.pari - Free module of degree 2 and rank 2 over Maximal order - of Rational function field in x over Finite Field of size 7 + Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: - [ 1 0] - [ 0 1/(x^3 + 1)] - """ - F = self.ring().fraction_field() - V, fr, to = F.vector_space() - O = F.base_field().maximal_order() - return V.span([to(g) for g in self.gens_over_base()], base_ring=O) - - @cached_method - def gens_over_base(self): + [x^2 + 1] + sage: V, from_V, to_V = K.vector_space(); V # optional - sage.libs.pari + Vector space of dimension 1 over Rational function field in x over Finite Field of size 7 + sage: I.module().is_submodule(V) # optional - sage.libs.pari + True """ - Return the generators of this ideal as a module over the maximal order - of the base rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari - (x^4 + x^2 + x, y + x) - - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari - (x^3 + 1, y + x) - """ - gens, d = self._gens_over_base - return tuple([~d * b for b in gens]) - - @lazy_attribute - def _gens_over_base(self): - """ - Return the generators of the integral ideal, which is the denominator - times the fractional ideal, together with the denominator. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I._gens_over_base # optional - sage.libs.pari - ([x, y], x) - """ - gens = [] - for row in self._hnf: - gens.append(sum([c1*c2 for c1,c2 in zip(row, self._ring.basis())])) - return gens, self._denominator - - def gens(self): - """ - Return a set of generators of this ideal. - - This provides whatever set of generators as quickly - as possible. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^4 + x^2 + x, y + x) - - sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^3 + 1, y + x) - """ - return self.gens_over_base() - - @cached_method - def basis_matrix(self): - """ - Return the matrix of basis vectors of this ideal as a module. - - The basis matrix is by definition the hermite norm form of the ideal - divided by the denominator. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari - sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.libs.pari - True - """ - d = self.denominator() - m = (d * self).hnf() - if d != 1: - m = ~d * m - m.set_immutable() - return m - - def is_integral(self): - """ - Return ``True`` if this is an integral ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari - sage: I.is_integral() # optional - sage.libs.pari - False - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.is_integral() # optional - sage.libs.pari - True - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari - sage: I.is_integral() # optional - sage.libs.pari - False - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.is_integral() # optional - sage.libs.pari - True - - sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular - sage: I.is_integral() # optional - sage.libs.singular - False - sage: J = I.denominator() * I # optional - sage.libs.singular - sage: J.is_integral() # optional - sage.libs.singular - True - """ - return self.denominator() == 1 - - def ideal_below(self): - """ - Return the ideal below this ideal. - - This is defined only for integral ideals. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari - Traceback (most recent call last): - ... - TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.ideal_below() # optional - sage.libs.pari - Ideal (x^3 + x^2 + x) of Maximal order of Rational function field - in x over Finite Field of size 2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari - Traceback (most recent call last): - ... - TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.ideal_below() # optional - sage.libs.pari - Ideal (x^3 + x) of Maximal order of Rational function field - in x over Finite Field of size 2 - - sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular - sage: I.ideal_below() # optional - sage.libs.singular - Traceback (most recent call last): - ... - TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.singular - sage: J.ideal_below() # optional - sage.libs.singular - Ideal (x^3 + x^2 + x) of Maximal order of Rational function field - in x over Rational Field - """ - if not self.is_integral(): - raise TypeError("not an integral ideal") - - K = self.ring().fraction_field().base_field().maximal_order() - - # self._hnf is in reversed hermite normal form, that is, lower - # triangular form. Thus the generator of the ideal below is - # just the (0,0) entry of the normal form. When self._hnf was in - # hermite normal form, that is, upper triangular form, then the - # generator can be computed in the following way: - # - # m = matrix([hnf[0].parent().gen(0)] + list(hnf)) - # _,T = m.hermite_form(transformation=True) - # return T[-1][0] - # - # This is certainly less efficient! This is an argument for using - # reversed hermite normal form for ideal representation. - l = self._hnf[0][0] - - return K.ideal(l) - - def norm(self): - """ - Return the norm of this fractional ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i1 = O.ideal(x) # optional - sage.libs.pari - sage: i2 = O.ideal(y) # optional - sage.libs.pari - sage: i3 = i1 * i2 # optional - sage.libs.pari - sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari - True - sage: i1.norm() # optional - sage.libs.pari - x^3 - sage: i1.norm() == x ** F.degree() # optional - sage.libs.pari - True - sage: i2.norm() # optional - sage.libs.pari - x^6 + x^4 + x^2 - sage: i2.norm() == y.norm() # optional - sage.libs.pari - True - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: i1 = O.ideal(x) # optional - sage.libs.pari - sage: i2 = O.ideal(y) # optional - sage.libs.pari - sage: i3 = i1 * i2 # optional - sage.libs.pari - sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari - True - sage: i1.norm() # optional - sage.libs.pari - x^2 - sage: i1.norm() == x ** L.degree() # optional - sage.libs.pari - True - sage: i2.norm() # optional - sage.libs.pari - (x^2 + 1)/x - sage: i2.norm() == y.norm() # optional - sage.libs.pari - True - """ - n = 1 - for e in self.basis_matrix().diagonal(): - n *= e - return n - - @cached_method - def is_prime(self): - """ - Return ``True`` if this ideal is a prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari - [True, True] - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari - [True, True] - - sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.singular - [True, True] - """ - factors = self.factor() - if len(factors) == 1 and factors[0][1] == 1: # prime! - prime = factors[0][0] - assert self == prime - self._relative_degree = prime._relative_degree - self._ramification_index = prime._ramification_index - self._prime_below = prime._prime_below - self._beta = prime._beta - self._beta_matrix = prime._beta_matrix - return True - else: - return False - - ################################################### - # The following methods are only for prime ideals # - ################################################### - - def valuation(self, ideal): - """ - Return the valuation of ``ideal`` at this prime ideal. - - INPUT: - - - ``ideal`` -- fractional ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) # optional - sage.libs.pari - sage: I.is_prime() # optional - sage.libs.pari - True - sage: J = O.ideal(y) # optional - sage.libs.pari - sage: I.valuation(J) # optional - sage.libs.pari - 2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari - [-1, 2] - - The method closely follows Algorithm 4.8.17 of [Coh1993]_. - """ - from sage.matrix.constructor import matrix - - if ideal.is_zero(): - return infinity - - O = self.ring() - F = O.fraction_field() - n = F.degree() - - # beta_matrix is for fast multiplication with beta. For performance, - # this is computed here rather than when the prime is constructed. - if self._beta_matrix is None: - beta = self._beta - m = [] - for i in range(n): - mtable_row = O._mtable[i] - c = sum(beta[j] * mtable_row[j] for j in range(n)) - m.append(c) - self._beta_matrix = matrix(m) - - B = self._beta_matrix - - # Step 1: compute the valuation of the denominator times the ideal - # - # This part is highly optimized as it is critical for - # overall performance of the function field machinery. - p = self.prime_below().gen().numerator() - h = ideal._hnf.list() - val = min([c.valuation(p) for c in h]) - i = self._ramification_index * val - while True: - ppow = p ** val - h = (matrix(n, [c // ppow for c in h]) * B).list() - val = min([c.valuation(p) for c in h]) - if val.is_zero(): - break - i += self._ramification_index * (val - 1) + 1 - - # Step 2: compute the valuation of the denominator - j = self._ramification_index * ideal.denominator().valuation(p) - - # Step 3: return the valuation - return i - j - - def prime_below(self): - """ - Return the prime lying below this prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari - [Ideal (x) of Maximal order of Rational function field in x - over Finite Field of size 2, Ideal (x^2 + x + 1) of Maximal order - of Rational function field in x over Finite Field of size 2] - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari - [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, - Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] - - sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.singular - [Ideal (x) of Maximal order of Rational function field in x over Rational Field, - Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Rational Field] - """ - return self._prime_below - - def _factor(self): - """ - Return the factorization of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I == I.factor().prod() # indirect doctest # optional - sage.libs.pari - True - """ - O = self.ring() - F = O.fraction_field() - o = F.base_field().maximal_order() - - # First we collect primes below self - d = self._denominator - i = d * self - - factors = [] - primes = set([o.ideal(p) for p,_ in d.factor()] + [p for p,_ in i.ideal_below().factor()]) - for prime in primes: - qs = [q[0] for q in O.decomposition(prime)] - for q in qs: - exp = q.valuation(self) - if exp != 0: - factors.append((q,exp)) - return factors - - -class FunctionFieldIdeal_global(FunctionFieldIdeal_polymod): - """ - Fractional ideals of canonical function fields - - INPUT: - - - ``ring`` -- order in a function field - - - ``hnf`` -- matrix in hermite normal form - - - ``denominator`` -- denominator - - The rows of ``hnf`` is a basis of the ideal, which itself is - ``denominator`` times the fractional ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.ideal(y) # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - """ - def __init__(self, ring, hnf, denominator=1): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(5)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari - """ - FunctionFieldIdeal_polymod.__init__(self, ring, hnf, denominator) - - def __pow__(self, mod): - """ - Return ``self`` to the power of ``mod``. - - If a two-generators representation of ``self`` is known, it is used - to speed up powering. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^7 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: S = I / J # optional - sage.libs.pari - sage: a = S^100 # optional - sage.libs.pari - sage: _ = S.gens_two() # optional - sage.libs.pari - sage: b = S^100 # faster # optional - sage.libs.pari - sage: b == I^100 / J^100 # optional - sage.libs.pari - True - sage: b == a # optional - sage.libs.pari - True - """ - if mod > 2 and self._gens_two_vecs is not None: - O = self._ring - mul = O._mul_vecs - R = self._hnf.base_ring() - n = self._hnf.ncols() - - I = matrix.identity(R, n) - - if len(self._gens_two_vecs) == 1: - p, = self._gens_two_vecs - ppow = p**mod - J = [ppow * v for v in I] - else: - p, q = self._gens_two_vecs - q = sum(e1 * e2 for e1,e2 in zip(O.basis(), q)) - ppow = p**mod - qpow = O._coordinate_vector(q**mod) - J = [ppow * v for v in I] + [mul(qpow,v) for v in I] - - return O._ideal_from_vectors_and_denominator(J, self._denominator**mod) - - return generic_power(self, mod) - - def gens(self): - """ - Return a set of generators of this ideal. - - This provides whatever set of generators as quickly - as possible. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^4 + x^2 + x, y + x) - - sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^3 + 1, y + x) - """ - if self._gens_two.is_in_cache(): - return self._gens_two.cache - else: - return self.gens_over_base() - - def gens_two(self): - r""" - Return two generators of this fractional ideal. - - If the ideal is principal, one generator *may* be returned. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I # indirect doctest # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field - in y defined by y^3 + x^6 + x^4 + x^2 - sage: ~I # indirect doctest # optional - sage.libs.pari - Ideal ((1/(x^6 + x^4 + x^2))*y^2) of Maximal order of Function field - in y defined by y^3 + x^6 + x^4 + x^2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I # indirect doctest # optional - sage.libs.pari - Ideal (y) of Maximal order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - sage: ~I # indirect doctest # optional - sage.libs.pari - Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order - of Function field in y defined by y^2 + y + (x^2 + 1)/x - """ - d = self.denominator() - return tuple(e/d for e in self._gens_two()) - - @cached_method - def _gens_two(self): - r""" - Return a set of two generators of the integral ideal, that is - the denominator times this fractional ideal. - - ALGORITHM: - - At most two generators are required to generate ideals in - Dedekind domains. - - Lemma 4.7.9, algorithm 4.7.10, and exercise 4.29 of [Coh1993]_ - tell us that for an integral ideal `I` in a number field, if - we pick `a` such that `\gcd(N(I), N(a)/N(I)) = 1`, then `a` - and `N(I)` generate the ideal. `N()` is the norm, and this - result (presumably) generalizes to function fields. - - After computing `N(I)`, we search exhaustively to find `a`. - - .. TODO:: - - Always return a single generator for a principal ideal. - - Testing for principality is not trivial. Algorithm 6.5.10 - of [Coh1993]_ could probably be adapted for function fields. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2,x*y,x+y) # optional - sage.libs.pari - sage: I._gens_two() # optional - sage.libs.pari - (x, y) - - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y-x) # optional - sage.libs.pari - sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.libs.pari - (x,) - """ - O = self.ring() - F = O.fraction_field() - - if self._kummer_form is not None: # prime ideal - _g1, _g2 = self._kummer_form - g1 = F(_g1) - g2 = sum([c1*c2 for c1,c2 in zip(_g2, O.basis())]) - if g2: - self._gens_two_vecs = (_g1, _g2) - return (g1,g2) - else: - self._gens_two_vecs = (_g1,) - return (g1,) - - ### start to search for two generators - - hnf = self._hnf - - norm = 1 - for e in hnf.diagonal(): - norm *= e - - if norm.is_constant(): # unit ideal - self._gens_two_vecs = (1,) - return (F(1),) - - # one generator; see .ideal_below() - _l = hnf[0][0] - p = _l.degree() - l = F(_l) - - if self._hnf == O.ideal(l)._hnf: # principal ideal - self._gens_two_vecs = (_l,) - return (l,) - - R = hnf.base_ring() - - basis = [] - for row in hnf: - basis.append(sum([c1*c2 for c1,c2 in zip(row, O.basis())])) - - n = len(basis) - alpha = None - - def check(alpha): - alpha_norm = alpha.norm().numerator() # denominator is 1 - return norm.gcd(alpha_norm // norm) == 1 - - # Trial 1: search for alpha among generators - for alpha in basis: - if check(alpha): - self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) - return (l, alpha) - - # Trial 2: exhaustive search for alpha using only polynomials - # with coefficients 0 or 1 - for d in range(p): - G = itertools.product(itertools.product([0,1],repeat=d+1), repeat=n) - for g in G: - alpha = sum([R(c1)*c2 for c1,c2 in zip(g, basis)]) - if check(alpha): - self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) - return (l, alpha) - - # Trial 3: exhaustive search for alpha using all polynomials - for d in range(p): - G = itertools.product(R.polynomials(max_degree=d), repeat=n) - for g in G: - # discard duplicate cases - if max(c.degree() for c in g) != d: - continue - for j in range(n): - if g[j] != 0: - break - if g[j].leading_coefficient() != 1: - continue - - alpha = sum([c1*c2 for c1,c2 in zip(g, basis)]) - if check(alpha): - self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) - return (l, alpha) - - # should not reach here - raise ValueError("no two generators found") - - -class FunctionFieldIdealInfinite(FunctionFieldIdeal): - """ - Base class of ideals of maximal infinite orders - """ - pass - - -class FunctionFieldIdealInfinite_rational(FunctionFieldIdealInfinite): - """ - Fractional ideal of the maximal order of rational function field. - - INPUT: - - - ``ring`` -- infinite maximal order - - - ``gen``-- generator - - Note that the infinite maximal order is a principal ideal domain. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(x) # optional - sage.libs.pari - Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 - """ - def __init__(self, ring, gen): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari - """ - FunctionFieldIdealInfinite.__init__(self, ring) - self._gen = gen - - def __hash__(self): - """ - Return the hash of this fractional ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: d = { I: 1, J: 2 } # optional - sage.libs.pari - """ - return hash( (self.ring(), self._gen) ) - - def __contains__(self, element): - """ - Test if ``element`` is in this ideal. - - INPUT: - - - ``element`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: O = K.maximal_order_infinite() - sage: I = O.ideal(1/(x+1)) - sage: x in I - False - sage: 1/x in I - True - sage: x/(x+1) in I - False - sage: 1/(x*(x+1)) in I - True - """ - return (element / self._gen) in self._ring - - def _richcmp_(self, other, op): - """ - Compare this ideal and ``other`` with respect to ``op``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+1) # optional - sage.libs.pari - sage: J = Oinf.ideal(x^2+x) # optional - sage.libs.pari - sage: I + J == J # optional - sage.libs.pari - True - """ - return richcmp(self._gen, other._gen, op) - - def _add_(self, other): - """ - Add this ideal with the other ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari - Ideal (1/x) of Maximal infinite order of Rational function field - in x over Finite Field of size 2 - """ - return self._ring.ideal([self._gen, other._gen]) - - def _mul_(self, other): - """ - Multiply this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari - Ideal (1/x^2) of Maximal infinite order of Rational function field - in x over Finite Field of size 2 - """ - return self._ring.ideal([self._gen * other._gen]) - - def _acted_upon_(self, other, on_left): - """ - Multiply this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: x * I # optional - sage.libs.pari - Ideal (1) of Maximal infinite order of Rational function field - in x over Finite Field of size 2 - """ - return self._ring.ideal([other * self._gen]) - - def __invert__(self): - """ - Return the multiplicative inverse of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari - sage: ~I # indirect doctest # optional - sage.libs.pari - Ideal (x) of Maximal infinite order of Rational function field in x - over Finite Field of size 2 - """ - return self._ring.ideal([~self._gen]) - - def is_prime(self): - """ - Return ``True`` if this ideal is a prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari - sage: I.is_prime() # optional - sage.libs.pari - True - """ - x = self._ring.fraction_field().gen() - return self._gen == 1/x - - def gen(self): - """ - Return the generator of this principal ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gen() # optional - sage.libs.pari - 1/x^2 - """ - return self._gen - - def gens(self): - """ - Return the generator of this principal ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (1/x^2,) - """ - return (self._gen,) - - def gens_over_base(self): - """ - Return the generator of this ideal as a rank one module - over the infinite maximal order. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari - (1/x^2,) - """ - return (self._gen,) - - def valuation(self, ideal): - """ - Return the valuation of ``ideal`` at this prime ideal. - - INPUT: - - - ``ideal`` -- fractional ideal - - EXAMPLES:: - - sage: F. = FunctionField(QQ) - sage: O = F.maximal_order_infinite() - sage: p = O.ideal(1/x) - sage: p.valuation(O.ideal(x/(x+1))) - 0 - sage: p.valuation(O.ideal(0)) - +Infinity - """ - if not self.is_prime(): - raise TypeError("not a prime ideal") - - f = ideal.gen() - if f == 0: - return infinity - else: - return f.denominator().degree() - f.numerator().degree() - - def _factor(self): - """ - Return the factorization of this ideal into prime ideals. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+1)) # optional - sage.libs.pari - sage: I._factor() # optional - sage.libs.pari - [(Ideal (1/x) of Maximal infinite order of Rational function field in x - over Finite Field of size 2, 2)] - """ - g = ~(self.ring().fraction_field().gen()) - m = self._gen.denominator().degree() - self._gen.numerator().degree() - if m == 0: - return [] - else: - return [(self.ring().ideal(g), m)] - - -class FunctionFieldIdealInfinite_module(FunctionFieldIdealInfinite, Ideal_generic): - """ - A fractional ideal specified by a finitely generated module over - the integers of the base field. - - INPUT: - - - ``ring`` -- order in a function field - - - ``module`` -- module - - EXAMPLES:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.ideal(y) # optional - sage.libs.singular - Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - """ - def __init__(self, ring, module): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: TestSuite(I).run() # optional - sage.libs.singular - """ - FunctionFieldIdealInfinite.__init__(self, ring) - - self._module = module - self._structure = ring.fraction_field().vector_space() - - V, from_V, to_V = self._structure - gens = tuple([from_V(a) for a in module.basis()]) - self._gens = gens - - # module generators are still ideal generators - Ideal_generic.__init__(self, ring, self._gens, coerce=False) - - def __contains__(self, x): - """ - Return ``True`` if ``x`` is in this ideal. - - INPUT: - - - ``x`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari - Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari - True - sage: y/x in I # optional - sage.libs.pari - False - sage: y^2 - 2 in I # optional - sage.libs.pari - True - """ - return self._structure[2](x) in self._module - - def __hash__(self): - """ - Return the hash of this ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari - sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari - """ - return hash((self._ring,self._module)) - - def __eq__(self, other): - """ - Test equality of this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari - sage: I == I + I # indirect doctest # optional - sage.libs.pari - True - """ - if not isinstance(other, FunctionFieldIdeal_module): - other = self.ring().ideal(other) - if self.ring() != other.ring(): - raise ValueError("rings must be the same") - - if (self.module().is_submodule(other.module()) and - other.module().is_submodule(self.module())): - return True - else: - return False - - def module(self): - """ - Return the module over the maximal order of the base field that - underlies this ideal. - - The formation of the module is compatible with the vector - space corresponding to the function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.maximal_order(); O # optional - sage.libs.pari - Maximal order of Rational function field in x over Finite Field of size 7 - sage: K.polynomial_ring() # optional - sage.libs.pari - Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7 - sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x^2 + 1,) - sage: I.module() # optional - sage.libs.pari - Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Finite Field of size 7 - Echelon basis matrix: - [x^2 + 1] - sage: V, from_V, to_V = K.vector_space(); V # optional - sage.libs.pari - Vector space of dimension 1 over Rational function field in x over Finite Field of size 7 - sage: I.module().is_submodule(V) # optional - sage.libs.pari - True - """ - return self._module - - -class FunctionFieldIdealInfinite_polymod(FunctionFieldIdealInfinite): - """ - Ideals of the infinite maximal order of an algebraic function field. - - INPUT: - - - ``ring`` -- infinite maximal order of the function field - - - ``ideal`` -- ideal in the inverted function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(1/y) # optional - sage.libs.pari - Ideal (1/x^4*y^2) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4 - """ - def __init__(self, ring, ideal): - """ - Initialize this ideal. - - TESTS:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari - """ - FunctionFieldIdealInfinite.__init__(self, ring) - self._ideal = ideal - - def __hash__(self): - """ - Return the hash of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: d = { I: 1 } # optional - sage.libs.pari - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: d = { I: 1 } # optional - sage.libs.pari - """ - return hash((self.ring(), self._ideal)) - - def __contains__(self, x): - """ - Return ``True`` if ``x`` is in this ideal. - - INPUT: - - - ``x`` -- element of the function field - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: 1/y in I # optional - sage.libs.pari - True - sage: 1/x in I # optional - sage.libs.pari - False - sage: 1/x^2 in I # optional - sage.libs.pari - True - """ - F = self.ring().fraction_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - return to_iF(x) in self._ideal - - def _add_(self, other): - """ - Add this ideal with the ``other`` ideal. - - INPUT: - - - ``ideal`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari - Ideal (1/x) of Maximal infinite order of Function field in y - defined by y^3 + y^2 + 2*x^4 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari - Ideal (1/x) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - """ - return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal + other._ideal) - - def _mul_(self, other): - """ - Multiply this ideal with the ``other`` ideal. - - INPUT: - - - ``other`` -- ideal - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari - Ideal (1/x^7*y^2) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari - Ideal (1/x^4*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - """ - return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal * other._ideal) - - def __pow__(self, n): - """ - Raise this ideal to ``n``-th power. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: J^3 # optional - sage.libs.pari - Ideal (1/x^3) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4 - """ - return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal ** n) - - def __invert__(self): - """ - Return the inverted ideal of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(y) # optional - sage.libs.pari - sage: ~J # optional - sage.libs.pari - Ideal (1/x^4*y^2) of Maximal infinite order - of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: J * ~J # optional - sage.libs.pari - Ideal (1) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(y) # optional - sage.libs.pari - sage: ~J # optional - sage.libs.pari - Ideal (1/x*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - sage: J * ~J # optional - sage.libs.pari - Ideal (1) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x - """ - return FunctionFieldIdealInfinite_polymod(self._ring, ~ self._ideal) - - def _richcmp_(self, other, op): - """ - Compare this ideal with the ``other`` ideal with respect to ``op``. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J == J * I # optional - sage.libs.pari - True - sage: I + J == J # optional - sage.libs.pari - True - sage: I + J == I # optional - sage.libs.pari - False - sage: (I < J) == (not J < I) # optional - sage.libs.pari - True - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J == J * I # optional - sage.libs.pari - True - sage: I + J == J # optional - sage.libs.pari - True - sage: I + J == I # optional - sage.libs.pari - False - sage: (I < J) == (not J < I) # optional - sage.libs.pari - True - """ - return richcmp(self._ideal, other._ideal, op) - - @property - def _relative_degree(self): - """ - Return the relative degree of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: [J._relative_degree for J,_ in I.factor()] # optional - sage.libs.pari - [1] - """ - if not self.is_prime(): - raise TypeError("not a prime ideal") - - return self._ideal._relative_degree - - def gens(self): - """ - Return a set of generators of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x, y, 1/x^2*y^2) - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari - (x, y) - """ - F = self.ring().fraction_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - return tuple(from_iF(b) for b in self._ideal.gens()) - - def gens_two(self): - """ - Return a set of at most two generators of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari - sage: I.gens_two() # optional - sage.libs.pari - (x, y) - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2+Y+x+1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari - sage: I.gens_two() # optional - sage.libs.pari - (x,) - """ - F = self.ring().fraction_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - return tuple(from_iF(b) for b in self._ideal.gens_two()) - - def gens_over_base(self): - """ - Return a set of generators of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari - (x, y, 1/x^2*y^2) - """ - F = self.ring().fraction_field() - iF,from_iF,to_iF = F._inversion_isomorphism() - return tuple(from_iF(g) for g in self._ideal.gens_over_base()) - - def ideal_below(self): - """ - Return a set of generators of this ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y^2) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari - Ideal (x^3) of Maximal order of Rational function field - in x over Finite Field in z2 of size 3^2 - """ - return self._ideal.ideal_below() - - def is_prime(self): - """ - Return ``True`` if this ideal is a prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari - (Ideal (1/x^3*y^2) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4)^3 - sage: I.is_prime() # optional - sage.libs.pari - False - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari - True - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari - (Ideal (1/x*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x)^2 - sage: I.is_prime() # optional - sage.libs.pari - False - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari - True - """ - return self._ideal.is_prime() - - @cached_method - def prime_below(self): - """ - Return the prime of the base order that underlies this prime ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari - (Ideal (1/x^3*y^2) of Maximal infinite order of Function field - in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari - True - sage: J.prime_below() # optional - sage.libs.pari - Ideal (1/x) of Maximal infinite order of Rational function field - in x over Finite Field in z2 of size 3^2 - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari - (Ideal (1/x*y) of Maximal infinite order of Function field in y - defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari - True - sage: J.prime_below() # optional - sage.libs.pari - Ideal (1/x) of Maximal infinite order of Rational function field in x - over Finite Field of size 2 - """ - if not self.is_prime(): - raise TypeError("not a prime ideal") - - F = self.ring().fraction_field() - K = F.base_field() - return K.maximal_order_infinite().prime_ideal() - - def valuation(self, ideal): - """ - Return the valuation of ``ideal`` with respect to this prime ideal. - - INPUT: - - - ``ideal`` -- fractional ideal - - EXAMPLES:: - - sage: K.=FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(y) # optional - sage.libs.pari - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari - [-1] - """ - if not self.is_prime(): - raise TypeError("not a prime ideal") - - return self._ideal.valuation(self.ring()._to_iF(ideal)) - - def _factor(self): - """ - Return factorization of the ideal. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: f= 1/x # optional - sage.libs.pari - sage: I = Oinf.ideal(f) # optional - sage.libs.pari - sage: I._factor() # optional - sage.libs.pari - [(Ideal (1/x, 1/x^4*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y - defined by y^3 + x^6 + x^4 + x^2, 1), - (Ideal (1/x, 1/x^2*y + 1) of Maximal infinite order of Function field in y - defined by y^3 + x^6 + x^4 + x^2, 1)] - """ - if self._ideal.is_prime.is_in_cache() and self._ideal.is_prime(): - return [(self, 1)] - - O = self.ring() - factors = [] - for iprime, exp in O._to_iF(self).factor(): - prime = FunctionFieldIdealInfinite_polymod(O, iprime) - factors.append((prime, exp)) - return factors + return self._module class IdealMonoid(UniqueRepresentation, Parent): diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index 8b19f6ce0c8..179499ea9de 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -94,6 +94,7 @@ - Brent Baccala (2019-12-20): support orders in characteristic zero """ + #***************************************************************************** # Copyright (C) 2010 William Stein # Copyright (C) 2011 Maarten Derickx @@ -105,10 +106,7 @@ # https://www.gnu.org/licenses/ #***************************************************************************** -import sage.rings.abc - from sage.categories.integral_domains import IntegralDomains -from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import from sage.structure.parent import Parent from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index e686228ae85..22cc02e9af0 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -4,6 +4,14 @@ Orders of function fields given by a basis over the maximal order of the base field """ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** from .ideal import FunctionFieldIdeal, FunctionFieldIdeal_module, FunctionFieldIdealInfinite_module from .order import FunctionFieldOrder, FunctionFieldOrderInfinite diff --git a/src/sage/rings/function_field/order_global.py b/src/sage/rings/function_field/order_global.py deleted file mode 100644 index 0c6b04ade88..00000000000 --- a/src/sage/rings/function_field/order_global.py +++ /dev/null @@ -1,363 +0,0 @@ -# sage.doctest: optional - sage.modules (because __init__ constructs a vector space) -# some tests are marked # optional - sage.libs.pari (because they use finite fields) -r""" -Maximal orders of global function fields -""" - -from sage.misc.cachefunc import cached_method - -from .ideal import FunctionFieldIdeal_global -from .order_polymod import FunctionFieldMaximalOrder_polymod - - -class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): - """ - Maximal orders of global function fields. - - INPUT: - - - ``field`` -- function field to which this maximal order belongs - - EXAMPLES:: - - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: L.maximal_order() - Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 - """ - - def __init__(self, field): - """ - Initialize. - - TESTS:: - - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: TestSuite(O).run() - """ - FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) - - @cached_method - def p_radical(self, prime): - """ - Return the ``prime``-radical of the maximal order. - - INPUT: - - - ``prime`` -- prime ideal of the maximal order of the base - rational function field - - The algorithm is outlined in Section 6.1.3 of [Coh1993]_. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x + 1) - sage: O.p_radical(p) - Ideal (x + 1) of Maximal order of Function field in y - defined by y^3 + x^6 + x^4 + x^2 - """ - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - g = prime.gens()[0] - - if not (g.denominator() == 1 and g.numerator().is_irreducible()): - raise ValueError('not a prime ideal') - - F = self.function_field() - n = F.degree() - o = prime.ring() - p = g.numerator() - - # Fp is isomorphic to the residue field o/p - Fp, fr_Fp, to_Fp = o._residue_field_global(p) - - # exp = q^j should be at least extension degree where q is - # the order of the residue field o/p - q = F.constant_base_field().order()**p.degree() - exp = q - while exp <= F.degree(): - exp = exp**q - - # radical equals to the kernel of the map x |-> x^exp - mat = [] - for g in self.basis(): - v = [to_Fp(c) for c in self._coordinate_vector(g**exp)] - mat.append(v) - mat = matrix(Fp, mat) - ker = mat.kernel() - - # construct module generators of the p-radical - vecs = [] - for i in range(n): - v = vector([p if j == i else 0 for j in range(n)]) - vecs.append(v) - for b in ker.basis(): - v = vector([fr_Fp(c) for c in b]) - vecs.append(v) - - return self._ideal_from_vectors(vecs) - - @cached_method - def decomposition(self, ideal): - """ - Return the decomposition of the prime ideal. - - INPUT: - - - ``ideal`` -- prime ideal of the base maximal order - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x + 1) - sage: O.decomposition(p) - [(Ideal (x + 1, y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), - (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order - of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - """ - from sage.matrix.constructor import matrix - - F = self.function_field() - n = F.degree() - - p = ideal.gen().numerator() - o = ideal.ring() - - # Fp is isomorphic to the residue field o/p - Fp, fr, to = o._residue_field_global(p) - P,X = Fp['X'].objgen() - - V = Fp**n # Ob = O/pO - - mtable = [] - for i in range(n): - row = [] - for j in range(n): - row.append( V([to(e) for e in self._mtable[i][j]]) ) - mtable.append(row) - - if p not in self._kummer_places: - ##################################### - # Decomposition by Kummer's theorem # - ##################################### - # gen is self._kummer_gen - gen_vec_pow = self._kummer_gen_vec_pow - mul_vecs = self._mul_vecs - - f = self._kummer_polynomial - fp = P([to(c.numerator()) for c in f.list()]) - decomposition = [] - for q, exp in fp.factor(): - # construct O.ideal([p,q(gen)]) - gen_vecs = list(matrix.diagonal(n * [p])) - c = q.list() - - # q(gen) in vector form - qgen = sum(fr(c[i]) * gen_vec_pow[i] for i in range(len(c))) - - I = matrix.identity(o._ring, n) - for i in range(n): - gen_vecs.append(mul_vecs(qgen,I[i])) - prime = self._ideal_from_vectors_and_denominator(gen_vecs) - - # Compute an element beta in O but not in pO. How to find beta - # is explained in Section 4.8.3 of [Coh1993]. We keep beta - # as a vector over k[x] with respect to the basis of O. - - # p and qgen generates the prime; modulo pO, qgenb generates the prime - qgenb = [to(qgen[i]) for i in range(n)] - m =[] - for i in range(n): - m.append(sum(qgenb[j] * mtable[i][j] for j in range(n))) - beta = [fr(coeff) for coeff in matrix(m).left_kernel().basis()[0]] - - prime.is_prime.set_cache(True) - prime._prime_below = ideal - prime._relative_degree = q.degree() - prime._ramification_index = exp - prime._beta = beta - - prime._kummer_form = (p, qgen) - - decomposition.append((prime, q.degree(), exp)) - else: - ############################# - # Buchman-Lenstra algorithm # - ############################# - from sage.matrix.special import block_matrix - from sage.modules.free_module_element import vector - - pO = self.ideal(p) - Ip = self.p_radical(ideal) - Ob = matrix.identity(Fp, n) - - def bar(I): # transfer to O/pO - m = [] - for v in I._hnf: - m.append([to(e) for e in v]) - h = matrix(m).echelon_form() - return cut_last_zero_rows(h) - - def liftb(Ib): - m = [vector([fr(e) for e in v]) for v in Ib] - m += [v for v in pO._hnf] - return self._ideal_from_vectors_and_denominator(m,1) - - def cut_last_zero_rows(h): - i = h.nrows() - while i > 0 and h.row(i-1).is_zero(): - i -= 1 - return h[:i] - - def mul_vec(v1,v2): - s = 0 - for i in range(n): - for j in range(n): - s += v1[i] * v2[j] * mtable[i][j] - return s - - def pow(v, r): # r > 0 - m = v - while r > 1: - m = mul_vec(m,v) - r -= 1 - return m - - # Algorithm 6.2.7 of [Coh1993] - def div(Ib, Jb): - # compute a basis of Jb/Ib - sJb = Jb.row_space() - sIb = Ib.row_space() - sJbsIb,proj_sJbsIb,lift_sJbsIb = sJb.quotient_abstract(sIb) - supplement_basis = [lift_sJbsIb(v) for v in sJbsIb.basis()] - - m = [] - for b in V.gens(): # basis of Ob = O/pO - b_row = [] # row vector representation of the map a -> a*b - for a in supplement_basis: - b_row += lift_sJbsIb(proj_sJbsIb( mul_vec(a,b) )) - m.append(b_row) - return matrix(Fp,n,m).left_kernel().basis_matrix() - - # Algorithm 6.2.5 of [Coh1993] - def mul(Ib, Jb): - m = [] - for v1 in Ib: - for v2 in Jb: - m.append(mul_vec(v1,v2)) - h = matrix(m).echelon_form() - return cut_last_zero_rows(h) - - def add(Ib,Jb): - m = block_matrix([[Ib], [Jb]]) - h = m.echelon_form() - return cut_last_zero_rows(h) - - # K_1, K_2, ... - Lb = IpOb = bar(Ip+pO) - Kb = [Lb] - while not Lb.is_zero(): - Lb = mul(Lb,IpOb) - Kb.append(Lb) - - # J_1, J_2, ... - Jb =[Kb[0]] + [div(Kb[j],Kb[j-1]) for j in range(1,len(Kb))] - - # H_1, H_2, ... - Hb = [div(Jb[j],Jb[j+1]) for j in range(len(Jb)-1)] + [Jb[-1]] - - q = Fp.order() - - def split(h): - # VsW represents O/H as a vector space - W = h.row_space() # H/pO - VsW,to_VsW,lift_to_V = V.quotient_abstract(W) - - # compute the space K of elements in O/H that satisfy a^q-a=0 - l = [lift_to_V(b) for b in VsW.basis()] - - images = [to_VsW(pow(x, q) - x) for x in l] - K = VsW.hom(images, VsW).kernel() - - if K.dimension() == 0: - return [] - if K.dimension() == 1: # h is prime - return [(liftb(h),VsW.dimension())] # relative degree - - # choose a such that a^q - a is 0 but a is not in Fp - for a in K.basis(): - # IMPORTANT: This criterion is based on the assumption - # that O.basis() starts with 1. - if a.support() != [0]: - break - else: - raise AssertionError("no appropriate value found") - - a = lift_to_V(a) - # compute the minimal polynomial of a - m = [to_VsW(Ob[0])] # 1 in VsW - apow = a - while True: - v = to_VsW(apow) - try: - sol = matrix(m).solve_left(v) - except ValueError: - m.append(v) - apow = mul_vec(apow, a) - continue - break - - minpol = X**len(sol) - P(list(sol)) - - # The minimal polynomial of a has only linear factors and at least two - # of them. We set f to the first factor and g to the product of the rest. - fac = minpol.factor() - f = fac[0][0] - g = (fac/f).expand() - d,u,v = f.xgcd(g) - - assert d == 1, "Not relatively prime {} and {}".format(f,g) - - # finally, idempotent! - e = lift_to_V(sum([c1*c2 for c1,c2 in zip(u*f,m)])) - - h1 = add(h, matrix([mul_vec(e,Ob[i]) for i in range(n)])) - h2 = add(h, matrix([mul_vec(Ob[0]-e,Ob[i]) for i in range(n)])) - - return split(h1) + split(h2) - - decomposition = [] - for i in range(len(Hb)): - index = i + 1 # Hb starts with H_1 - for prime, degree in split(Hb[i]): - # Compute an element beta in O but not in pO. How to find beta - # is explained in Section 4.8.3 of [Coh1993]. We keep beta - # as a vector over k[x] with respect to the basis of O. - m =[] - for i in range(n): - r = [] - for g in prime._hnf: - r += sum(to(g[j]) * mtable[i][j] for j in range(n)) - m.append(r) - beta = [fr(e) for e in matrix(m).left_kernel().basis()[0]] - - prime.is_prime.set_cache(True) - prime._prime_below = ideal - prime._relative_degree = degree - prime._ramification_index = index - prime._beta = beta - - decomposition.append((prime, degree, index)) - - return decomposition diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 8e458b3458b..9e2e0124d68 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -1,16 +1,24 @@ -# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) -# sage.doctest: optional - sage.modules (because __init__ constructs a vector space) r""" Orders of function fields - polymod implementation """ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + from sage.arith.functions import lcm from sage.misc.cachefunc import cached_method from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from .ideal import ( - FunctionFieldIdeal, +from .ideal import FunctionFieldIdeal +from .ideal_polymod import ( FunctionFieldIdeal_polymod, + FunctionFieldIdeal_global, FunctionFieldIdealInfinite_polymod ) from .order import FunctionFieldMaximalOrder, FunctionFieldMaximalOrderInfinite @@ -35,7 +43,7 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): FunctionFieldMaximalOrder.__init__(self, field, ideal_class) from sage.modules.free_module_element import vector - from .function_field import FunctionField_integral + from .function_field_polymod import FunctionField_integral if isinstance(field, FunctionField_integral): basis = field._maximal_order_basis() @@ -1070,3 +1078,357 @@ def coordinate_vector(self, e): ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) """ return self._module.coordinate_vector(self._to_module(e)) + + +class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): + """ + Maximal orders of global function fields. + + INPUT: + + - ``field`` -- function field to which this maximal order belongs + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: L.maximal_order() + Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 + """ + + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(7)); R. = K[] + sage: L. = K.extension(y^4 + x*y + 4*x + 1) + sage: O = L.maximal_order() + sage: TestSuite(O).run() + """ + FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) + + @cached_method + def p_radical(self, prime): + """ + Return the ``prime``-radical of the maximal order. + + INPUT: + + - ``prime`` -- prime ideal of the maximal order of the base + rational function field + + The algorithm is outlined in Section 6.1.3 of [Coh1993]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] + sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) + sage: o = K.maximal_order() + sage: O = F.maximal_order() + sage: p = o.ideal(x + 1) + sage: O.p_radical(p) + Ideal (x + 1) of Maximal order of Function field in y + defined by y^3 + x^6 + x^4 + x^2 + """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + g = prime.gens()[0] + + if not (g.denominator() == 1 and g.numerator().is_irreducible()): + raise ValueError('not a prime ideal') + + F = self.function_field() + n = F.degree() + o = prime.ring() + p = g.numerator() + + # Fp is isomorphic to the residue field o/p + Fp, fr_Fp, to_Fp = o._residue_field_global(p) + + # exp = q^j should be at least extension degree where q is + # the order of the residue field o/p + q = F.constant_base_field().order()**p.degree() + exp = q + while exp <= F.degree(): + exp = exp**q + + # radical equals to the kernel of the map x |-> x^exp + mat = [] + for g in self.basis(): + v = [to_Fp(c) for c in self._coordinate_vector(g**exp)] + mat.append(v) + mat = matrix(Fp, mat) + ker = mat.kernel() + + # construct module generators of the p-radical + vecs = [] + for i in range(n): + v = vector([p if j == i else 0 for j in range(n)]) + vecs.append(v) + for b in ker.basis(): + v = vector([fr_Fp(c) for c in b]) + vecs.append(v) + + return self._ideal_from_vectors(vecs) + + @cached_method + def decomposition(self, ideal): + """ + Return the decomposition of the prime ideal. + + INPUT: + + - ``ideal`` -- prime ideal of the base maximal order + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) + sage: o = K.maximal_order() + sage: O = F.maximal_order() + sage: p = o.ideal(x + 1) + sage: O.decomposition(p) + [(Ideal (x + 1, y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), + (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order + of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] + """ + from sage.matrix.constructor import matrix + + F = self.function_field() + n = F.degree() + + p = ideal.gen().numerator() + o = ideal.ring() + + # Fp is isomorphic to the residue field o/p + Fp, fr, to = o._residue_field_global(p) + P,X = Fp['X'].objgen() + + V = Fp**n # Ob = O/pO + + mtable = [] + for i in range(n): + row = [] + for j in range(n): + row.append( V([to(e) for e in self._mtable[i][j]]) ) + mtable.append(row) + + if p not in self._kummer_places: + ##################################### + # Decomposition by Kummer's theorem # + ##################################### + # gen is self._kummer_gen + gen_vec_pow = self._kummer_gen_vec_pow + mul_vecs = self._mul_vecs + + f = self._kummer_polynomial + fp = P([to(c.numerator()) for c in f.list()]) + decomposition = [] + for q, exp in fp.factor(): + # construct O.ideal([p,q(gen)]) + gen_vecs = list(matrix.diagonal(n * [p])) + c = q.list() + + # q(gen) in vector form + qgen = sum(fr(c[i]) * gen_vec_pow[i] for i in range(len(c))) + + I = matrix.identity(o._ring, n) + for i in range(n): + gen_vecs.append(mul_vecs(qgen,I[i])) + prime = self._ideal_from_vectors_and_denominator(gen_vecs) + + # Compute an element beta in O but not in pO. How to find beta + # is explained in Section 4.8.3 of [Coh1993]. We keep beta + # as a vector over k[x] with respect to the basis of O. + + # p and qgen generates the prime; modulo pO, qgenb generates the prime + qgenb = [to(qgen[i]) for i in range(n)] + m =[] + for i in range(n): + m.append(sum(qgenb[j] * mtable[i][j] for j in range(n))) + beta = [fr(coeff) for coeff in matrix(m).left_kernel().basis()[0]] + + prime.is_prime.set_cache(True) + prime._prime_below = ideal + prime._relative_degree = q.degree() + prime._ramification_index = exp + prime._beta = beta + + prime._kummer_form = (p, qgen) + + decomposition.append((prime, q.degree(), exp)) + else: + ############################# + # Buchman-Lenstra algorithm # + ############################# + from sage.matrix.special import block_matrix + from sage.modules.free_module_element import vector + + pO = self.ideal(p) + Ip = self.p_radical(ideal) + Ob = matrix.identity(Fp, n) + + def bar(I): # transfer to O/pO + m = [] + for v in I._hnf: + m.append([to(e) for e in v]) + h = matrix(m).echelon_form() + return cut_last_zero_rows(h) + + def liftb(Ib): + m = [vector([fr(e) for e in v]) for v in Ib] + m += [v for v in pO._hnf] + return self._ideal_from_vectors_and_denominator(m,1) + + def cut_last_zero_rows(h): + i = h.nrows() + while i > 0 and h.row(i-1).is_zero(): + i -= 1 + return h[:i] + + def mul_vec(v1,v2): + s = 0 + for i in range(n): + for j in range(n): + s += v1[i] * v2[j] * mtable[i][j] + return s + + def pow(v, r): # r > 0 + m = v + while r > 1: + m = mul_vec(m,v) + r -= 1 + return m + + # Algorithm 6.2.7 of [Coh1993] + def div(Ib, Jb): + # compute a basis of Jb/Ib + sJb = Jb.row_space() + sIb = Ib.row_space() + sJbsIb,proj_sJbsIb,lift_sJbsIb = sJb.quotient_abstract(sIb) + supplement_basis = [lift_sJbsIb(v) for v in sJbsIb.basis()] + + m = [] + for b in V.gens(): # basis of Ob = O/pO + b_row = [] # row vector representation of the map a -> a*b + for a in supplement_basis: + b_row += lift_sJbsIb(proj_sJbsIb( mul_vec(a,b) )) + m.append(b_row) + return matrix(Fp,n,m).left_kernel().basis_matrix() + + # Algorithm 6.2.5 of [Coh1993] + def mul(Ib, Jb): + m = [] + for v1 in Ib: + for v2 in Jb: + m.append(mul_vec(v1,v2)) + h = matrix(m).echelon_form() + return cut_last_zero_rows(h) + + def add(Ib,Jb): + m = block_matrix([[Ib], [Jb]]) + h = m.echelon_form() + return cut_last_zero_rows(h) + + # K_1, K_2, ... + Lb = IpOb = bar(Ip+pO) + Kb = [Lb] + while not Lb.is_zero(): + Lb = mul(Lb,IpOb) + Kb.append(Lb) + + # J_1, J_2, ... + Jb =[Kb[0]] + [div(Kb[j],Kb[j-1]) for j in range(1,len(Kb))] + + # H_1, H_2, ... + Hb = [div(Jb[j],Jb[j+1]) for j in range(len(Jb)-1)] + [Jb[-1]] + + q = Fp.order() + + def split(h): + # VsW represents O/H as a vector space + W = h.row_space() # H/pO + VsW,to_VsW,lift_to_V = V.quotient_abstract(W) + + # compute the space K of elements in O/H that satisfy a^q-a=0 + l = [lift_to_V(b) for b in VsW.basis()] + + images = [to_VsW(pow(x, q) - x) for x in l] + K = VsW.hom(images, VsW).kernel() + + if K.dimension() == 0: + return [] + if K.dimension() == 1: # h is prime + return [(liftb(h),VsW.dimension())] # relative degree + + # choose a such that a^q - a is 0 but a is not in Fp + for a in K.basis(): + # IMPORTANT: This criterion is based on the assumption + # that O.basis() starts with 1. + if a.support() != [0]: + break + else: + raise AssertionError("no appropriate value found") + + a = lift_to_V(a) + # compute the minimal polynomial of a + m = [to_VsW(Ob[0])] # 1 in VsW + apow = a + while True: + v = to_VsW(apow) + try: + sol = matrix(m).solve_left(v) + except ValueError: + m.append(v) + apow = mul_vec(apow, a) + continue + break + + minpol = X**len(sol) - P(list(sol)) + + # The minimal polynomial of a has only linear factors and at least two + # of them. We set f to the first factor and g to the product of the rest. + fac = minpol.factor() + f = fac[0][0] + g = (fac/f).expand() + d,u,v = f.xgcd(g) + + assert d == 1, "Not relatively prime {} and {}".format(f,g) + + # finally, idempotent! + e = lift_to_V(sum([c1*c2 for c1,c2 in zip(u*f,m)])) + + h1 = add(h, matrix([mul_vec(e,Ob[i]) for i in range(n)])) + h2 = add(h, matrix([mul_vec(Ob[0]-e,Ob[i]) for i in range(n)])) + + return split(h1) + split(h2) + + decomposition = [] + for i in range(len(Hb)): + index = i + 1 # Hb starts with H_1 + for prime, degree in split(Hb[i]): + # Compute an element beta in O but not in pO. How to find beta + # is explained in Section 4.8.3 of [Coh1993]. We keep beta + # as a vector over k[x] with respect to the basis of O. + m =[] + for i in range(n): + r = [] + for g in prime._hnf: + r += sum(to(g[j]) * mtable[i][j] for j in range(n)) + m.append(r) + beta = [fr(e) for e in matrix(m).left_kernel().basis()[0]] + + prime.is_prime.set_cache(True) + prime._prime_below = ideal + prime._relative_degree = degree + prime._ramification_index = index + prime._beta = beta + + decomposition.append((prime, degree, index)) + + return decomposition + diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index 4f36af13442..c9a045e2bb3 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -1,8 +1,16 @@ -# some tests are marked # optional - sage.libs.pari (because they use finite fields) r""" Orders of rational function fields """ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + import sage.rings.abc from sage.arith.functions import lcm @@ -11,11 +19,8 @@ from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.rings.number_field.number_field_base import NumberField -from .ideal import ( - FunctionFieldIdeal, - FunctionFieldIdeal_rational, - FunctionFieldIdealInfinite_rational, -) +from .ideal import FunctionFieldIdeal +from .ideal_rational import FunctionFieldIdeal_rational, FunctionFieldIdealInfinite_rational from .order import FunctionFieldMaximalOrder, FunctionFieldMaximalOrderInfinite diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index fe1bbd908bd..8458ff77f67 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -46,6 +46,7 @@ - Brent Baccala (2019-12-20): function fields of characteristic zero """ + #***************************************************************************** # Copyright (C) 2016 Kwankyu Lee # @@ -55,20 +56,10 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -import sage.rings.abc - -from sage.misc.cachefunc import cached_method - -from sage.arith.functions import lcm - -from sage.rings.integer_ring import ZZ -from sage.rings.number_field.number_field_base import NumberField - from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.richcmp import richcmp - from sage.categories.sets_cat import Sets @@ -320,812 +311,6 @@ def divisor(self, multiplicity=1): return prime_divisor(self.function_field(), self, multiplicity) -class FunctionFieldPlace_rational(FunctionFieldPlace): - """ - Places of rational function fields. - """ - def degree(self): - """ - Return the degree of the place. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: p = i.place() # optional - sage.libs.pari - sage: p.degree() # optional - sage.libs.pari - 2 - """ - if self.is_infinite_place(): - return 1 - else: - return self._prime.gen().numerator().degree() - - def is_infinite_place(self): - """ - Return ``True`` if the place is at infinite. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari - [Place (1/x), Place (x), Place (x + 1)] - sage: [p.is_infinite_place() for p in F.places()] # optional - sage.libs.pari - [True, False, False] - """ - F = self.function_field() - return self.prime_ideal().ring() == F.maximal_order_infinite() - - def local_uniformizer(self): - """ - Return a local uniformizer of the place. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari - [Place (1/x), Place (x), Place (x + 1)] - sage: [p.local_uniformizer() for p in F.places()] # optional - sage.libs.pari - [1/x, x, x + 1] - """ - return self.prime_ideal().gen() - - def residue_field(self, name=None): - """ - Return the residue field of the place. - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari - sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari - Finite Field in z2 of size 2^2 - sage: fr_k # optional - sage.libs.pari - Ring morphism: - From: Finite Field in z2 of size 2^2 - To: Valuation ring at Place (x^2 + x + 1) - sage: to_k # optional - sage.libs.pari - Ring morphism: - From: Valuation ring at Place (x^2 + x + 1) - To: Finite Field in z2 of size 2^2 - """ - return self.valuation_ring().residue_field(name=name) - - def _residue_field(self, name=None): - """ - Return the residue field of the place along with the maps from - and to it. - - INPUT: - - - ``name`` -- string; name of the generator of the residue field - - EXAMPLES:: - - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: p = i.place() # optional - sage.libs.pari - sage: R, fr, to = p._residue_field() # optional - sage.libs.pari - sage: R # optional - sage.libs.pari - Finite Field in z2 of size 2^2 - sage: [fr(e) for e in R.list()] # optional - sage.libs.pari - [0, x, x + 1, 1] - sage: to(x*(x+1)) == to(x) * to(x+1) # optional - sage.libs.pari - True - """ - F = self.function_field() - prime = self.prime_ideal() - - if self.is_infinite_place(): - K = F.constant_base_field() - - def from_K(e): - return F(e) - - def to_K(f): - n = f.numerator() - d = f.denominator() - - n_deg = n.degree() - d_deg =d.degree() - - if n_deg < d_deg: - return K(0) - elif n_deg == d_deg: - return n.lc() / d.lc() - else: - raise TypeError("not in the valuation ring") - else: - O = F.maximal_order() - K, from_K, _to_K = O._residue_field(prime, name=name) - - def to_K(f): - if f in O: # f.denominator() is 1 - return _to_K(f.numerator()) - else: - d = F(f.denominator()) - n = d * f - - nv = prime.valuation(O.ideal(n)) - dv = prime.valuation(O.ideal(d)) - - if nv > dv: - return K(0) - elif dv > nv: - raise TypeError("not in the valuation ring") - - s = ~prime.gen() - rd = d * s**dv # in O but not in prime - rn = n * s**nv # in O but not in prime - return to_K(rn) / to_K(rd) - - return K, from_K, to_K - - def valuation_ring(self): - """ - Return the valuation ring at the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: p.valuation_ring() # optional - sage.libs.pari - Valuation ring at Place (x, x*y) - """ - from .valuation_ring import FunctionFieldValuationRing - - return FunctionFieldValuationRing(self.function_field(), self) - - -class FunctionFieldPlace_polymod(FunctionFieldPlace): - """ - Places of extensions of function fields. - """ - def place_below(self): - """ - Return the place lying below the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.place_below() # optional - sage.libs.pari - Place (x^2 + x + 1) - """ - return self.prime_ideal().prime_below().place() - - def relative_degree(self): - """ - Return the relative degree of the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.relative_degree() # optional - sage.libs.pari - 1 - """ - return self._prime._relative_degree - - def degree(self): - """ - Return the degree of the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.degree() # optional - sage.libs.pari - 2 - """ - return self.relative_degree() * self.place_below().degree() - - def is_infinite_place(self): - """ - Return ``True`` if the place is above the unique infinite place - of the underlying rational function field. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: pls = L.places() # optional - sage.libs.pari - sage: [p.is_infinite_place() for p in pls] # optional - sage.libs.pari - [True, True, False] - sage: [p.place_below() for p in pls] # optional - sage.libs.pari - [Place (1/x), Place (1/x), Place (x)] - """ - return self.place_below().is_infinite_place() - - def local_uniformizer(self): - """ - Return an element of the function field that has a simple zero - at the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: pls = L.places() # optional - sage.libs.pari - sage: [p.local_uniformizer().valuation(p) for p in pls] # optional - sage.libs.pari - [1, 1, 1, 1, 1] - """ - gens = self._prime.gens() - for g in gens: - if g.valuation(self) == 1: - return g - assert False, "Internal error" - - def gaps(self): - """ - Return the gap sequence for the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari - sage: p.gaps() # a Weierstrass place # optional - sage.libs.pari - [1, 2, 4] - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: [p.gaps() for p in L.places()] # optional - sage.libs.pari - [[1, 2, 4], [1, 2, 4], [1, 2, 4]] - """ - if self.degree() == 1: - return self._gaps_rational() # faster for rational places - else: - return self._gaps_wronskian() - - def _gaps_rational(self): - """ - Return the gap sequence for the rational place. - - This method computes the gap numbers using the definition of gap - numbers. The dimension of the multiple of the prime divisor - supported at the place is computed by Hess' algorithm. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari - sage: p.gaps() # indirect doctest # optional - sage.libs.pari - [1, 2, 4] - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.libs.pari - [[1, 2, 4], [1, 2, 4], [1, 2, 4]] - """ - from sage.matrix.constructor import matrix - - F = self.function_field() - n = F.degree() - O = F.maximal_order() - Oinf = F.maximal_order_infinite() - - R = O._module_base_ring._ring - one = R.one() - - # Hess' Riemann-Roch basis algorithm stripped down for gaps computation - def dim_RR(M): - den = lcm([e.denominator() for e in M.list()]) - mat = matrix(R, M.nrows(), [(den*e).numerator() for e in M.list()]) - - # initialise pivot_row and conflicts list - pivot_row = [[] for i in range(n)] - conflicts = [] - for i in range(n): - bestp = -1 - best = -1 - for c in range(n): - d = mat[i,c].degree() - if d >= best: - bestp = c - best = d - - if best >= 0: - pivot_row[bestp].append((i,best)) - if len(pivot_row[bestp]) > 1: - conflicts.append(bestp) - - # while there is a conflict, do a simple transformation - while conflicts: - c = conflicts.pop() - row = pivot_row[c] - i,ideg = row.pop() - j,jdeg = row.pop() - - if jdeg > ideg: - i,j = j,i - ideg,jdeg = jdeg,ideg - - coeff = - mat[i,c].lc() / mat[j,c].lc() - s = coeff * one.shift(ideg - jdeg) - - mat.add_multiple_of_row(i, j, s) - - row.append((j,jdeg)) - - bestp = -1 - best = -1 - for c in range(n): - d = mat[i,c].degree() - if d >= best: - bestp = c - best = d - - if best >= 0: - pivot_row[bestp].append((i,best)) - if len(pivot_row[bestp]) > 1: - conflicts.append(bestp) - - dim = 0 - for j in range(n): - i,ideg = pivot_row[j][0] - k = den.degree() - ideg + 1 - if k > 0: - dim += k - return dim - - V,fr,to = F.vector_space() - - prime_inv = ~ self.prime_ideal() - I = O.ideal(1) - J = Oinf.ideal(1) - - B = matrix([to(b) for b in J.gens_over_base()]) - C = matrix([to(v) for v in I.gens_over_base()]) - - prev = dim_RR(C * B.inverse()) - gaps = [] - g = F.genus() - i = 1 - if self.is_infinite_place(): - while g: - J = J * prime_inv - B = matrix([to(b) for b in J.gens_over_base()]) - dim = dim_RR(C * B.inverse()) - if dim == prev: - gaps.append(i) - g -= 1 - else: - prev = dim - i += 1 - else: # self is a finite place - Binv = B.inverse() - while g: - I = I * prime_inv - C = matrix([to(v) for v in I.gens_over_base()]) - dim = dim_RR(C * Binv) - if dim == prev: - gaps.append(i) - g -= 1 - else: - prev = dim - i += 1 - - return gaps - - def _gaps_wronskian(self): - """ - Return the gap sequence for the place. - - This method implements the local version of Hess' Algorithm 30 of [Hes2002b]_ - based on the Wronskian determinant. - - EXAMPLES:: - - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari - sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari - [1, 2, 4] - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.libs.pari - [[1, 2, 4], [1, 2, 4], [1, 2, 4]] - """ - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - F = self.function_field() - R,fr_R,to_R = self._residue_field() - der = F.higher_derivation() - - sep = self.local_uniformizer() - - # a differential divisor satisfying - # v_p(W) = 0 for the place p - W = sep.differential().divisor() - - # Step 3: - basis = W._basis() - d = len(basis) - M = matrix([to_R(b) for b in basis]) - if M.rank() == 0: - return [] - - # Steps 4, 5, 6, 7: - e = 1 - gaps = [1] - while M.nrows() < d: - row = vector([to_R(der._derive(basis[i], e, sep)) for i in range(d)]) - if row not in M.row_space(): - M = matrix(M.rows() + [row]) - M.echelonize() - gaps.append(e + 1) - e += 1 - - return gaps - - def residue_field(self, name=None): - """ - Return the residue field of the place. - - INPUT: - - - ``name`` -- string; name of the generator of the residue field - - OUTPUT: - - - a field isomorphic to the residue field - - - a ring homomorphism from the valuation ring to the field - - - a ring homomorphism from the field to the valuation ring - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari - Finite Field of size 2 - sage: fr_k # optional - sage.libs.pari - Ring morphism: - From: Finite Field of size 2 - To: Valuation ring at Place (x, x*y) - sage: to_k # optional - sage.libs.pari - Ring morphism: - From: Valuation ring at Place (x, x*y) - To: Finite Field of size 2 - sage: to_k(y) # optional - sage.libs.pari - Traceback (most recent call last): - ... - TypeError: y fails to convert into the map's domain - Valuation ring at Place (x, x*y)... - sage: to_k(1/y) # optional - sage.libs.pari - 0 - sage: to_k(y/(1+y)) # optional - sage.libs.pari - 1 - """ - return self.valuation_ring().residue_field(name=name) - - @cached_method - def _residue_field(self, name=None): - """ - Return the residue field of the place along with the functions - mapping from and to it. - - INPUT: - - - ``name`` -- string (default: `None`); name of the generator - of the residue field - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: k,fr_k,to_k = p._residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari - Finite Field of size 2 - sage: [fr_k(e) for e in k] # optional - sage.libs.pari - [0, 1] - - :: - - sage: K. = FunctionField(GF(9)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.pari - sage: p = L.places()[-1] # optional - sage.libs.pari - sage: p.residue_field() # optional - sage.libs.pari - (Finite Field in z2 of size 3^2, Ring morphism: - From: Finite Field in z2 of size 3^2 - To: Valuation ring at Place (x + 1, y + 2*z2), Ring morphism: - From: Valuation ring at Place (x + 1, y + 2*z2) - To: Finite Field in z2 of size 3^2) - - :: - - sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular - sage: O = K.maximal_order() - sage: I = O.ideal(x) - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular - [(Rational Field, Ring morphism: - From: Rational Field - To: Valuation ring at Place (x, y, y^2), Ring morphism: - From: Valuation ring at Place (x, y, y^2) - To: Rational Field), - (Number Field in s with defining polynomial x^2 - 2*x + 2, Ring morphism: - From: Number Field in s with defining polynomial x^2 - 2*x + 2 - To: Valuation ring at Place (x, x*y, y^2 + 1), Ring morphism: - From: Valuation ring at Place (x, x*y, y^2 + 1) - To: Number Field in s with defining polynomial x^2 - 2*x + 2)] - sage: for p in L.places_above(I.place()): # optional - sage.libs.singular - ....: k, fr_k, to_k = p.residue_field() - ....: assert all(fr_k(k(e)) == e for e in range(10)) - ....: assert all(to_k(fr_k(e)) == e for e in [k.random_element() for i in [1..10]]) - - :: - - sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field - sage: I = O.ideal(x) # optional - sage.libs.singular sage.rings.number_field - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular sage.rings.number_field - [(Algebraic Field, Ring morphism: - From: Algebraic Field - To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: - From: Valuation ring at Place (x, y - I, y^2 + 1) - To: Algebraic Field), (Algebraic Field, Ring morphism: - From: Algebraic Field - To: Valuation ring at Place (x, y, y^2), Ring morphism: - From: Valuation ring at Place (x, y, y^2) - To: Algebraic Field), (Algebraic Field, Ring morphism: - From: Algebraic Field - To: Valuation ring at Place (x, y + I, y^2 + 1), Ring morphism: - From: Valuation ring at Place (x, y + I, y^2 + 1) - To: Algebraic Field)] - """ - F = self.function_field() - prime = self.prime_ideal() # Let P be this prime ideal - - if self.is_infinite_place(): - _F, from_F, to_F = F._inversion_isomorphism() - _prime = prime._ideal - _place = _prime.place() - - K, _from_K, _to_K = _place._residue_field(name=name) - - from_K = lambda e: from_F(_from_K(e)) - to_K = lambda f: _to_K(to_F(f)) - return K, from_K, to_K - - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - - O = F.maximal_order() - Obasis = O.basis() - - M = prime.hnf() - R = M.base_ring() # univariate polynomial ring - n = M.nrows() # extension degree of the function field - - # Step 1: construct a vector space representing the residue field - # - # Given an (reversed) HNF basis M for a prime ideal P of O, every - # element of O mod P can be represented by a vector of polynomials of - # degrees less than those of the (anti)diagonal elements of M. In turn, - # the vector of polynomials can be represented by the vector of the - # coefficients of the polynomials. V is the space of these vectors. - - k = F.constant_base_field() - degs = [M[i,i].degree() for i in range(n)] - deg = sum(degs) # degree of the place - - # Let V = k**deg - - def to_V(e): - """ - An example to show the idea: Suppose that:: - - [x 0 0] - M = [0 1 0] and v = (x^10, x^7 + x^3, x^7 + x^4 + x^3 + 1) - [1 0 1] - - Then to_V(e) = [1] - """ - v = O._coordinate_vector(e) - vec = [] - for i in reversed(range(n)): - q,r = v[i].quo_rem(M[i,i]) - v -= q * M[i] - for j in range(degs[i]): - vec.append(r[j]) - return vector(vec) - - def fr_V(vec): # to_O - vec = vec.list() - pos = 0 - e = F(0) - for i in reversed(range(n)): - if degs[i] == 0: - continue - else: - end = pos + degs[i] - e += R(vec[pos:end]) * Obasis[i] - pos = end - return e - - # Step 2: find a primitive element of the residue field - - def candidates(): - # Trial 1: this suffices for places obtained from Kummers' theorem - # and for places of function fields over number fields or QQbar - - # Note that a = O._kummer_gen is a simple generator of O/prime over - # o/p. If b is a simple generator of o/p over the constant base field - # k, then the set a + k * b contains a simple generator of O/prime - # over k (as there are finite number of intermediate fields). - a = O._kummer_gen - if a is not None: - K,fr_K,_ = self.place_below().residue_field() - b = fr_K(K.gen()) - if isinstance(k, (NumberField, sage.rings.abc.AlgebraicField)): - kk = ZZ - else: - kk = k - for c in kk: - if c != 0: - yield a + c * b - - # Trial 2: basis elements of the maximal order - for gen in reversed(Obasis): - yield gen - - import itertools - - # Trial 3: exhaustive search in O using only polynomials - # with coefficients 0 or 1 - for d in range(deg): - G = itertools.product(itertools.product([0,1],repeat=d+1), repeat=n) - for g in G: - gen = sum([R(c1)*c2 for c1,c2 in zip(g, Obasis)]) - yield gen - - # Trial 4: exhaustive search in O using all polynomials - for d in range(deg): - G = itertools.product(R.polynomials(max_degree=d), repeat=n) - for g in G: - # discard duplicate cases - if max(c.degree() for c in g) != d: - continue - for j in range(n): - if g[j] != 0: - break - if g[j].leading_coefficient() != 1: - continue - - gen = sum([c1*c2 for c1,c2 in zip(g, Obasis)]) - yield gen - - # Search for a primitive element. It is such an element g of O - # whose powers span the vector space V. - for gen in candidates(): - g = F.one() - m = [] - for i in range(deg): - m.append(to_V(g)) - g *= gen - mat = matrix(m) - if mat.rank() == deg: - break - - # Step 3: compute the minimal polynomial of g - min_poly = R((-mat.solve_left(to_V(g))).list() + [1]) - - # Step 4: construct the residue field K as an extension of the base - # constant field using the minimal polynomial and compute vector space - # representation W of K along with maps between them - if deg > 1: - if isinstance(k, NumberField): - if name is None: - name='s' - K = k.extension(min_poly, names=name) - - def from_W(e): - return K(list(e)) - - def to_W(e): - return vector(K(e)) - else: - K = k.extension(deg, name=name) - - # primitive element in K corresponding to g in O mod P - prim = min_poly.roots(K)[0][0] - - W, from_W, to_W = K.vector_space(k, basis=[prim**i for i in range(deg)], map=True) - else: # deg == 1 - K = k - - def from_W(e): - return K(e[0]) - - def to_W(e): - return vector([e]) - - # Step 5: compute the matrix of change of basis, from V to W via K - C = mat.inverse() - - # Step 6: construct the maps between the residue field of the valuation - # ring at P and K, via O and V and W - - def from_K(e): - return fr_V(to_W(e) * mat) - - # As explained in Section 4.8.3 of [Coh1993]_, alpha has a simple pole - # at this place and no other poles at finite places. - p = prime.prime_below().gen().numerator() - beta = prime._beta - alpha = ~p * sum(c1*c2 for c1,c2 in zip(beta, Obasis)) - alpha_powered_by_ramification_index = alpha ** prime._ramification_index - - def to_K(f): - if f not in O: - den = O.coordinate_vector(f).denominator() - num = den * f - - # s powered by the valuation of den at the prime - alpha_power = alpha_powered_by_ramification_index ** den.valuation(p) - rn = num * alpha_power # in O - rd = den * alpha_power # in O but not in prime - - # Note that rn is not in O if and only if f is - # not in the valuation ring. Hence f is in the - # valuation ring if and only if this procedure - # does not fall into an infinite loop. - return to_K(rn) / to_K(rd) - - return from_W(to_V(f) * C) - - return K, from_K, to_K - - def valuation_ring(self): - """ - Return the valuation ring at the place. - - EXAMPLES:: - - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: p.valuation_ring() # optional - sage.libs.pari - Valuation ring at Place (x, x*y) - """ - from .valuation_ring import FunctionFieldValuationRing - - return FunctionFieldValuationRing(self.function_field(), self) - - class PlaceSet(UniqueRepresentation, Parent): """ Sets of Places of function fields. diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index 2b5bfd4bf94..aa7591ac71d 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -43,7 +43,7 @@ from sage.interfaces.singular import singular from sage.rings.rational_field import is_RationalField -from sage.rings.function_field.function_field import RationalFunctionField +from sage.rings.function_field.function_field_rational import RationalFunctionField from sage.rings.finite_rings.finite_field_base import is_FiniteField from sage.rings.integer_ring import ZZ @@ -162,7 +162,7 @@ def _do_singular_init_(singular, base_ring, char, _vars, order): return singular(f"std(ideal({base_ring.__minpoly}))", type='qring'), None - elif isinstance(base_ring, sage.rings.function_field.function_field.RationalFunctionField) \ + elif isinstance(base_ring, sage.rings.function_field.function_field_rational.RationalFunctionField) \ and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) return make_ring(f"({base_ring.characteristic()},{gen})"), None diff --git a/src/sage/rings/valuation/valuations_catalog.py b/src/sage/rings/valuation/valuations_catalog.py index 0d0f3362768..69e064a10c1 100644 --- a/src/sage/rings/valuation/valuations_catalog.py +++ b/src/sage/rings/valuation/valuations_catalog.py @@ -1,5 +1,5 @@ from sage.rings.padics.padic_valuation import pAdicValuation -from sage.rings.function_field.function_field_valuation import FunctionFieldValuation +from sage.rings.function_field.valuation import FunctionFieldValuation from .gauss_valuation import GaussValuation from .trivial_valuation import TrivialDiscretePseudoValuation, TrivialPseudoValuation, TrivialValuation from .limit_valuation import LimitValuation From 36f456a1f2888ee3985e519671feddd43b3c444d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 15 Mar 2023 12:02:53 +0900 Subject: [PATCH 24/54] Fix failures in sage/rings/valuation --- src/sage/rings/valuation/augmented_valuation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/valuation/augmented_valuation.py b/src/sage/rings/valuation/augmented_valuation.py index e4834e38f0b..37fda19d7dc 100644 --- a/src/sage/rings/valuation/augmented_valuation.py +++ b/src/sage/rings/valuation/augmented_valuation.py @@ -1109,7 +1109,7 @@ def lift(self, F): # We only have to do that if psi is non-trivial if self.psi().degree() > 1: from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement - from sage.rings.function_field.element import FunctionFieldElement_polymod + from sage.rings.function_field.element_polymod import FunctionFieldElement_polymod from sage.rings.number_field.number_field_element import NumberFieldElement_relative from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing if isinstance(F, PolynomialQuotientRingElement): From 43130d0f30f5b2e05a215b5dd30d4aa431081496 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 15 Mar 2023 14:22:24 +0900 Subject: [PATCH 25/54] Add new files --- .../function_field/derivations_polymod.py | 892 ++++++ .../function_field/derivations_rational.py | 113 + src/sage/rings/function_field/element.pxd | 10 + .../rings/function_field/element_polymod.pyx | 396 +++ .../rings/function_field/element_rational.pyx | 500 ++++ .../function_field/function_field_polymod.py | 2535 +++++++++++++++++ .../function_field/function_field_rational.py | 992 +++++++ .../rings/function_field/ideal_polymod.py | 1693 +++++++++++ .../rings/function_field/ideal_rational.py | 605 ++++ .../rings/function_field/place_polymod.py | 663 +++++ .../rings/function_field/place_rational.py | 175 ++ src/sage/rings/function_field/valuation.py | 1482 ++++++++++ 12 files changed, 10056 insertions(+) create mode 100644 src/sage/rings/function_field/derivations_polymod.py create mode 100644 src/sage/rings/function_field/derivations_rational.py create mode 100644 src/sage/rings/function_field/element.pxd create mode 100644 src/sage/rings/function_field/element_polymod.pyx create mode 100644 src/sage/rings/function_field/element_rational.pyx create mode 100644 src/sage/rings/function_field/function_field_polymod.py create mode 100644 src/sage/rings/function_field/function_field_rational.py create mode 100644 src/sage/rings/function_field/ideal_polymod.py create mode 100644 src/sage/rings/function_field/ideal_rational.py create mode 100644 src/sage/rings/function_field/place_polymod.py create mode 100644 src/sage/rings/function_field/place_rational.py create mode 100644 src/sage/rings/function_field/valuation.py diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py new file mode 100644 index 00000000000..6d59aef7158 --- /dev/null +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -0,0 +1,892 @@ +from sage.arith.misc import binomial +from sage.categories.homset import Hom +from sage.categories.map import Map +from sage.categories.sets_cat import Sets +from sage.rings.derivation import RingDerivationWithoutTwist + +from .derivations import FunctionFieldDerivation + + +class FunctionFieldDerivation_separable(FunctionFieldDerivation): + """ + Derivations of separable extensions. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: L.derivation() + d/dx + """ + def __init__(self, parent, d): + """ + Initialize a derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``d`` -- a variable name or a derivation over + the base field (or something capable to create + such a derivation) + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: TestSuite(d).run() + + sage: L.derivation(y) # d/dy + 2*y*d/dx + + sage: dK = K.derivation([x]); dK + x*d/dx + sage: L.derivation(dK) + x*d/dx + """ + FunctionFieldDerivation.__init__(self, parent) + L = parent.domain() + C = parent.codomain() + dm = parent._defining_morphism + u = L.gen() + if d == L.gen(): + d = parent._base_derivation(None) + f = L.polynomial().change_ring(L) + coeff = -f.derivative()(u) / f.map_coefficients(d)(u) + if dm is not None: + coeff = dm(coeff) + self._d = parent._base_derivation([coeff]) + self._gen_image = C.one() + else: + if isinstance(d, RingDerivationWithoutTwist) and d.domain() is L.base_ring(): + self._d = d + else: + self._d = d = parent._base_derivation(d) + f = L.polynomial() + if dm is None: + denom = f.derivative()(u) + else: + u = dm(u) + denom = f.derivative().map_coefficients(dm, new_base_ring=C)(u) + num = f.map_coefficients(d, new_base_ring=C)(u) + self._gen_image = -num / denom + + def _call_(self, x): + r""" + Evaluate the derivation on ``x``. + + INPUT: + + - ``x`` -- element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d(x) # indirect doctest + 1 + sage: d(y) + 1/2/x*y + sage: d(y^2) + 1 + """ + parent = self.parent() + if x.is_zero(): + return parent.codomain().zero() + x = x._x + y = parent.domain().gen() + dm = parent._defining_morphism + tmp1 = x.map_coefficients(self._d, new_base_ring=parent.codomain()) + tmp2 = x.derivative()(y) + if dm is not None: + tmp2 = dm(tmp2) + y = dm(y) + return tmp1(y) + tmp2 * self._gen_image + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d + d/dx + sage: d + d + 2*d/dx + """ + return type(self)(self.parent(), self._d + other._d) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) + sage: d = L.derivation() + sage: d + d/dx + sage: y * d + y*d/dx + """ + return type(self)(self.parent(), factor * self._d) + + +class FunctionFieldDerivation_inseparable(FunctionFieldDerivation): + def __init__(self, parent, u=None): + r""" + Initialize this derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``u`` -- a parameter describing the derivation + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + + This also works for iterated non-monic extensions:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari + sage: M.derivation() # optional - sage.libs.pari + d/dz + + We can also create a multiple of the canonical derivation:: + + sage: M.derivation([x]) # optional - sage.libs.pari + x*d/dz + """ + FunctionFieldDerivation.__init__(self, parent) + if u is None: + self._u = parent.codomain().one() + elif u == 0 or isinstance(u, (list, tuple)): + if u == 0 or len(u) == 0: + self._u = parent.codomain().zero() + elif len(u) == 1: + self._u = parent.codomain()(u[0]) + else: + raise ValueError("the length does not match") + else: + raise ValueError("you must pass in either a name of a variable or a list of coefficients") + + def _call_(self, x): + r""" + Evaluate the derivation on ``x``. + + INPUT: + + - ``x`` -- an element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d(x) # indirect doctest # optional - sage.libs.pari + 0 + sage: d(y) # optional - sage.libs.pari + 1 + sage: d(y^2) # optional - sage.libs.pari + 0 + + """ + if x.is_zero(): + return self.codomain().zero() + parent = self.parent() + return self._u * parent._d(parent._t(x)) + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari + d/dy + sage: d + d # optional - sage.libs.pari + 2*d/dy + """ + return type(self)(self.parent(), [self._u + other._u]) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: d = L.derivation() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari + d/dy + sage: y * d # optional - sage.libs.pari + y*d/dy + """ + return type(self)(self.parent(), [factor * self._u]) + + +class FunctionFieldHigherDerivation(Map): + """ + Base class of higher derivations on function fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.higher_derivation() # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + """ + Map.__init__(self, Hom(field, field, Sets())) + self._field = field + # elements of a prime finite field do not have pth_root method + if field.constant_base_field().is_prime_field(): + self._pth_root_func = _pth_root_in_prime_field + else: + self._pth_root_func = _pth_root_in_finite_field + + def _repr_type(self) -> str: + """ + Return a string containing the type of the map. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # indirect doctest # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + """ + return 'Higher derivation' + + def __eq__(self, other) -> bool: + """ + Test if ``self`` equals ``other``. + + TESTS:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: loads(dumps(h)) == h # optional - sage.libs.pari + True + """ + if isinstance(other, FunctionFieldHigherDerivation): + return self._field == other._field + return False + + +def _pth_root_in_prime_field(e): + """ + Return the `p`-th root of element ``e`` in a prime finite field. + + TESTS:: + + sage: from sage.rings.function_field.derivations_polymod import _pth_root_in_prime_field + sage: p = 5 + sage: F. = GF(p) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari + True + """ + return e + + +def _pth_root_in_finite_field(e): + """ + Return the `p`-th root of element ``e`` in a finite field. + + TESTS:: + + sage: from sage.rings.function_field.derivations_polymod import _pth_root_in_finite_field + sage: p = 3 + sage: F. = GF(p^2) # optional - sage.libs.pari + sage: e = F.random_element() # optional - sage.libs.pari + sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari + True + """ + return e.pth_root() + + +class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): + """ + Higher derivations of rational function fields over finite fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari + Higher derivation map: + From: Rational function field in x over Finite Field of size 2 + To: Rational function field in x over Finite Field of size 2 + sage: h(x^2,2) # optional - sage.libs.pari + 1 + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + """ + FunctionFieldHigherDerivation.__init__(self, field) + + self._p = field.characteristic() + self._separating_element = field.gen() + + def _call_with_args(self, f, args=(), kwds={}): + """ + Call the derivation with args and kwds. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari + 1 + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return the `i`-th derivative of ``f`` with respect to the + separating element. + + This implements Hess' Algorithm 26 in [Hes2002b]_. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._derive(x^3,0) # optional - sage.libs.pari + x^3 + sage: h._derive(x^3,1) # optional - sage.libs.pari + x^2 + sage: h._derive(x^3,2) # optional - sage.libs.pari + x + sage: h._derive(x^3,3) # optional - sage.libs.pari + 1 + sage: h._derive(x^3,4) # optional - sage.libs.pari + 0 + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + prime_power_representation = self._prime_power_representation + + def derive(f, i): + # Step 1: zero-th derivative + if i == 0: + return f + # Step 2: + s = i % p + r = i // p + # Step 3: + e = f + while s > 0: + e = derivative(e) / F(s) + s -= 1 + # Step 4: + if r == 0: + return e + else: + # Step 5: + lambdas = prime_power_representation(e, x) + # Step 6 and 7: + der = 0 + for i in range(p): + mu = derive(lambdas[i], r) + der += mu**p * x**i + return der + + return derive(f, i) + + def _prime_power_representation(self, f, separating_element=None): + """ + Return `p`-th power representation of the element ``f``. + + Here `p` is the characteristic of the function field. + + This implements Hess' Algorithm 25. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari + [x + 1, 1] + sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari + True + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + # Step 1: + a = [f] + aprev = f + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + # Step 2: + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) + for i in range(j + 1, p)) + j -= 1 + # Step 3 + return [self._pth_root(c) for c in b] + + def _pth_root(self, c): + """ + Return the `p`-th root of the rational function ``c``. + + INPUT: + + - ``c`` -- rational function + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: h = F.higher_derivation() # optional - sage.libs.pari + sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari + x^2 + 1 + """ + K = self._field + p = self._p + + R = K._field.ring() + + poly = c.numerator() + num = R([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + poly = c.denominator() + den = R([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + return K.element_class(K, num / den) + + +class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): + """ + Higher derivations of global function fields. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h # optional - sage.libs.pari sage.modules + Higher derivation map: + From: Function field in y defined by y^3 + x^3*y + x + To: Function field in y defined by y^3 + x^3*y + x + sage: h(y^2, 2) # optional - sage.libs.pari sage.modules + ((x^7 + 1)/x^2)*y^2 + x^3*y + """ + + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari sage.modules + """ + from sage.matrix.constructor import matrix + + FunctionFieldHigherDerivation.__init__(self, field) + + self._p = field.characteristic() + self._separating_element = field(field.base_field().gen()) + + p = field.characteristic() + y = field.gen() + + # matrix for pth power map; used in _prime_power_representation method + self.__pth_root_matrix = matrix([(y**(i * p)).list() + for i in range(field.degree())]).transpose() + + # cache computed higher derivatives to speed up later computations + self._cache = {} + + def _call_with_args(self, f, args, kwds): + """ + Call the derivation with ``args`` and ``kwds``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari sage.modules + ((x^7 + 1)/x^2)*y^2 + x^3*y + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return ``i``-th derivative of ``f`` with respect to the separating + element. + + This implements Hess' Algorithm 26 in [Hes2002b]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: y^3 # optional - sage.libs.pari sage.modules + x^3*y + x + sage: h._derive(y^3,0) # optional - sage.libs.pari sage.modules + x^3*y + x + sage: h._derive(y^3,1) # optional - sage.libs.pari sage.modules + x^4*y^2 + 1 + sage: h._derive(y^3,2) # optional - sage.libs.pari sage.modules + x^10*y^2 + (x^8 + x)*y + sage: h._derive(y^3,3) # optional - sage.libs.pari sage.modules + (x^9 + x^2)*y^2 + x^7*y + sage: h._derive(y^3,4) # optional - sage.libs.pari sage.modules + (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y + """ + F = self._field + p = self._p + frob = F.frobenius_endomorphism() # p-th power map + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + try: + cache = self._cache[separating_element] + except KeyError: + cache = self._cache[separating_element] = {} + + def derive(f, i): + # Step 1: zero-th derivative + if i == 0: + return f + + # Step 1.5: use cached result if available + try: + return cache[f, i] + except KeyError: + pass + + # Step 2: + s = i % p + r = i // p + # Step 3: + e = f + while s > 0: + e = derivative(e) / F(s) + s -= 1 + # Step 4: + if r == 0: + der = e + else: + # Step 5: inlined self._prime_power_representation + a = [e] + aprev = e + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(k, j) * b[k] * x**(k - j) + for k in range(j + 1, p)) + j -= 1 + lambdas = [self._pth_root(c) for c in b] + + # Step 6 and 7: + der = 0 + xpow = 1 + for k in range(p): + mu = derive(lambdas[k], r) + der += frob(mu) * xpow + xpow *= x + + cache[f, i] = der + return der + + return derive(f, i) + + def _prime_power_representation(self, f, separating_element=None): + """ + Return `p`-th power representation of the element ``f``. + + Here `p` is the characteristic of the function field. + + This implements Hess' Algorithm 25 in [Hes2002b]_. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: b = h._prime_power_representation(y) # optional - sage.libs.pari sage.modules + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari sage.modules + True + """ + F = self._field + p = self._p + + if separating_element is None: + x = self._separating_element + + def derivative(f): + return f.derivative() + else: + x = separating_element + xderinv = ~(x.derivative()) + + def derivative(f): + return xderinv * f.derivative() + + # Step 1: + a = [f] + aprev = f + j = 1 + while j < p: + aprev = derivative(aprev) / F(j) + a.append(aprev) + j += 1 + # Step 2: + b = a + j = p - 2 + while j >= 0: + b[j] -= sum(binomial(i, j) * b[i] * x**(i - j) + for i in range(j + 1, p)) + j -= 1 + # Step 3 + return [self._pth_root(c) for c in b] + + def _pth_root(self, c): + """ + Return the `p`-th root of function field element ``c``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari sage.modules + y^2 + x^2 + """ + from sage.modules.free_module_element import vector + + K = self._field.base_field() # rational function field + p = self._p + + coeffs = [] + for d in self.__pth_root_matrix.solve_right(vector(c.list())): + poly = d.numerator() + num = K([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + poly = d.denominator() + den = K([self._pth_root_func(poly[i]) + for i in range(0, poly.degree() + 1, p)]) + coeffs.append(num / den) + return self._field(coeffs) + + +class FunctionFieldHigherDerivation_char_zero(FunctionFieldHigherDerivation): + """ + Higher derivations of function fields of characteristic zero. + + INPUT: + + - ``field`` -- function field on which the derivation operates + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: h + Higher derivation map: + From: Function field in y defined by y^3 + x^3*y + x + To: Function field in y defined by y^3 + x^3*y + x + sage: h(y,1) == -(3*x^2*y+1)/(3*y^2+x^3) + True + sage: h(y^2,1) == -2*y*(3*x^2*y+1)/(3*y^2+x^3) + True + sage: e = L.random_element() + sage: h(h(e,1),1) == 2*h(e,2) + True + sage: h(h(h(e,1),1),1) == 3*2*h(e,3) + True + """ + def __init__(self, field): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: TestSuite(h).run(skip=['_test_category']) + """ + FunctionFieldHigherDerivation.__init__(self, field) + + self._separating_element = field(field.base_field().gen()) + + # cache computed higher derivatives to speed up later computations + self._cache = {} + + def _call_with_args(self, f, args, kwds): + """ + Call the derivation with ``args`` and ``kwds``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: e = L.random_element() + sage: h(h(e,1),1) == 2*h(e,2) # indirect doctest + True + """ + return self._derive(f, *args, **kwds) + + def _derive(self, f, i, separating_element=None): + """ + Return ``i``-th derivative of ``f`` with respect to the separating + element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) + sage: h = L.higher_derivation() + sage: y^3 + -x^3*y - x + sage: h._derive(y^3,0) + -x^3*y - x + sage: h._derive(y^3,1) + (-21/4*x^4/(x^7 + 27/4))*y^2 + ((-9/2*x^9 - 45/2*x^2)/(x^7 + 27/4))*y + (-9/2*x^7 - 27/4)/(x^7 + 27/4) + """ + F = self._field + + if separating_element is None: + x = self._separating_element + xderinv = 1 + else: + x = separating_element + xderinv = ~(x.derivative()) + + try: + cache = self._cache[separating_element] + except KeyError: + cache = self._cache[separating_element] = {} + + if i == 0: + return f + + try: + return cache[f, i] + except KeyError: + pass + + s = i + e = f + while s > 0: + e = xderinv * e.derivative() / F(s) + s -= 1 + + der = e + + cache[f, i] = der + return der + diff --git a/src/sage/rings/function_field/derivations_rational.py b/src/sage/rings/function_field/derivations_rational.py new file mode 100644 index 00000000000..a7c72853661 --- /dev/null +++ b/src/sage/rings/function_field/derivations_rational.py @@ -0,0 +1,113 @@ +from .derivations import FunctionFieldDerivation + + +class FunctionFieldDerivation_rational(FunctionFieldDerivation): + """ + Derivations on rational function fields. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.derivation() + d/dx + """ + def __init__(self, parent, u=None): + """ + Initialize a derivation. + + INPUT: + + - ``parent`` -- the parent of this derivation + + - ``u`` -- a parameter describing the derivation + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: TestSuite(d).run() + + The parameter ``u`` can be the name of the variable:: + + sage: K.derivation(x) + d/dx + + or a list of length one whose unique element is the image + of the generator of the underlying function field:: + + sage: K.derivation([x^2]) + x^2*d/dx + """ + FunctionFieldDerivation.__init__(self, parent) + if u is None or u == parent.domain().gen(): + self._u = parent.codomain().one() + elif u == 0 or isinstance(u, (list, tuple)): + if u == 0 or len(u) == 0: + self._u = parent.codomain().zero() + elif len(u) == 1: + self._u = parent.codomain()(u[0]) + else: + raise ValueError("the length does not match") + else: + raise ValueError("you must pass in either a name of a variable or a list of coefficients") + + def _call_(self, x): + """ + Compute the derivation of ``x``. + + INPUT: + + - ``x`` -- element of the rational function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d(x) # indirect doctest + 1 + sage: d(x^3) + 3*x^2 + sage: d(1/x) + -1/x^2 + """ + f = x.numerator() + g = x.denominator() + numerator = f.derivative() * g - f * g.derivative() + if numerator.is_zero(): + return self.codomain().zero() + else: + v = numerator / g**2 + defining_morphism = self.parent()._defining_morphism + if defining_morphism is not None: + v = defining_morphism(v) + return self._u * v + + def _add_(self, other): + """ + Return the sum of this derivation and ``other``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d + 2*d/dx + """ + return type(self)(self.parent(), [self._u + other._u]) + + def _lmul_(self, factor): + """ + Return the product of this derivation by the scalar ``factor``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: d = K.derivation() + sage: d + d/dx + sage: x * d + x*d/dx + """ + return type(self)(self.parent(), [factor * self._u]) + + diff --git a/src/sage/rings/function_field/element.pxd b/src/sage/rings/function_field/element.pxd new file mode 100644 index 00000000000..f0418634f82 --- /dev/null +++ b/src/sage/rings/function_field/element.pxd @@ -0,0 +1,10 @@ +from sage.structure.element cimport FieldElement + + +cdef class FunctionFieldElement(FieldElement): + cdef readonly object _x + cdef readonly object _matrix + + cdef FunctionFieldElement _new_c(self) + cpdef bint is_nth_power(self, n) + cpdef FunctionFieldElement nth_root(self, n) diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx new file mode 100644 index 00000000000..2a542030fda --- /dev/null +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -0,0 +1,396 @@ + +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.richcmp cimport richcmp, richcmp_not_equal +from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element + +from sage.rings.function_field.element cimport FunctionFieldElement + + +cdef class FunctionFieldElement_polymod(FunctionFieldElement): + """ + Elements of a finite extension of a function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: x*y + 1/x^3 # optional - sage.libs.singular + x*y + 1/x^3 + """ + def __init__(self, parent, x, reduce=True): + """ + Initialize. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: TestSuite(x*y + 1/x^3).run() # optional - sage.libs.singular + """ + FieldElement.__init__(self, parent) + if reduce: + self._x = x % self._parent.polynomial() + else: + self._x = x + + def element(self): + """ + Return the underlying polynomial that represents the element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(T^2 - x*T + 4*x^3) # optional - sage.libs.singular + sage: f = y/x^2 + x/(x^2+1); f # optional - sage.libs.singular + 1/x^2*y + x/(x^2 + 1) + sage: f.element() # optional - sage.libs.singular + 1/x^2*y + x/(x^2 + 1) + """ + return self._x + + def _repr_(self): + """ + Return the string representation of the element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y._repr_() # optional - sage.libs.singular + 'y' + """ + return self._x._repr(name=self.parent().variable_name()) + + def __bool__(self): + """ + Return True if the element is not zero. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: bool(y) # optional - sage.libs.singular + True + sage: bool(L(0)) # optional - sage.libs.singular + False + sage: bool(L.coerce(L.polynomial())) # optional - sage.libs.singular + False + """ + return not not self._x + + def __hash__(self): + """ + Return the hash of the element. + + TESTS:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 # optional - sage.libs.singular + True + """ + return hash(self._x) + + cpdef _richcmp_(self, other, int op): + """ + Do rich comparison with the other element with respect to ``op`` + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: L(0) == 0 # optional - sage.libs.singular + True + sage: y != L(2) # optional - sage.libs.singular + True + """ + cdef FunctionFieldElement left = self + cdef FunctionFieldElement right = other + return richcmp(left._x, right._x, op) + + cpdef _add_(self, right): + """ + Add the element with the other element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + (5*x + 5)*y + x/(x^3 + 1) + sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest # optional - sage.libs.singular + True + sage: -y + y # optional - sage.libs.singular + 0 + """ + cdef FunctionFieldElement res = self._new_c() + res._x = self._x + (right)._x + return res + + cpdef _sub_(self, right): + """ + Subtract the other element from the element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + (-5*x - 1)*y + x/(x^3 + 1) + sage: y - y # optional - sage.libs.singular + 0 + """ + cdef FunctionFieldElement res = self._new_c() + res._x = self._x - (right)._x + return res + + cpdef _mul_(self, right): + """ + Multiply the element with the other element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: y * (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3 + """ + cdef FunctionFieldElement res = self._new_c() + res._x = (self._x * (right)._x) % self._parent.polynomial() + return res + + cpdef _div_(self, right): + """ + Divide the element with the other element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest # optional - sage.libs.singular + 1 + sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest # optional - sage.libs.singular + Traceback (most recent call last): + ... + ZeroDivisionError: Cannot invert 0 + """ + return self * ~right + + def __invert__(self): + """ + Return the multiplicative inverse of the element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: a = ~(2*y + 1/x); a # indirect doctest # optional - sage.libs.singular + (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) + sage: a*(2*y + 1/x) # optional - sage.libs.singular + 1 + """ + if self.is_zero(): + raise ZeroDivisionError("Cannot invert 0") + P = self._parent + return P(self._x.xgcd(P._polynomial)[1]) + + cpdef list list(self): + """ + Return the list of the coefficients representing the element. + + If the function field is `K[y]/(f(y))`, then return the coefficients of + the reduced presentation of the element as a polynomial in `K[y]`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular + sage: a = ~(2*y + 1/x); a # optional - sage.libs.singular + (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) + sage: a.list() # optional - sage.libs.singular + [(1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16), -1/8*x^2/(x^5 + 1/8*x^2 + 1/16)] + sage: (x*y).list() # optional - sage.libs.singular + [0, x] + """ + return self._x.padded_list(self._parent.degree()) + + cpdef FunctionFieldElement nth_root(self, n): + r""" + Return an ``n``-th root of this element in the function field. + + INPUT: + + - ``n`` -- an integer + + OUTPUT: + + Returns an element ``a`` in the function field such that this element + equals `a^n`. Raises an error if no such element exists. + + ALGORITHM: + + If ``n`` is a power of the characteristic of the field and the constant + base field is perfect, then this uses the algorithm described in + Proposition 12 of [GiTr1996]_. + + .. SEEALSO:: + + :meth:`is_nth_power` + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L(y^3).nth_root(3) # optional - sage.libs.pari + y + sage: L(y^9).nth_root(-9) # optional - sage.libs.pari + 1/x*y + + This also works for inseparable extensions:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - x^2) # optional - sage.libs.pari + sage: L(x).nth_root(3)^3 # optional - sage.libs.pari + x + sage: L(x^9).nth_root(-27)^-27 # optional - sage.libs.pari + x^9 + + """ + if n == 1: + return self + if n < 0: + return (~self).nth_root(-n) + if n == 0: + if not self.is_one(): + raise ValueError("element is not a 0-th power") + return self + + # reduce to the separable case + poly = self._parent._polynomial + if not poly.gcd(poly.derivative()).is_one(): + L, from_L, to_L = self._parent.separable_model(('t', 'w')) + return from_L(to_L(self).nth_root(n)) + + constant_base_field = self._parent.constant_base_field() + p = constant_base_field.characteristic() + if p.divides(n) and constant_base_field.is_perfect(): + return self._pth_root().nth_root(n//p) + + raise NotImplementedError("nth_root() not implemented for this n") + + cpdef bint is_nth_power(self, n): + r""" + Return whether this element is an ``n``-th power in the function field. + + INPUT: + + - ``n`` -- an integer + + ALGORITHM: + + If ``n`` is a power of the characteristic of the field and the constant + base field is perfect, then this uses the algorithm described in + Proposition 12 of [GiTr1996]_. + + .. SEEALSO:: + + :meth:`nth_root` + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: y.is_nth_power(2) # optional - sage.libs.pari + False + sage: L(x).is_nth_power(2) # optional - sage.libs.pari + True + + """ + if n == 0: + return self.is_one() + if n == 1: + return True + if n < 0: + return self.is_unit() and (~self).is_nth_power(-n) + + # reduce to the separable case + poly = self._parent._polynomial + if not poly.gcd(poly.derivative()).is_one(): + L, from_L, to_L = self._parent.separable_model(('t', 'w')) + return to_L(self).is_nth_power(n) + + constant_base_field = self._parent.constant_base_field() + p = constant_base_field.characteristic() + if p.divides(n) and constant_base_field.is_perfect(): + return self._parent.derivation()(self).is_zero() and self._pth_root().is_nth_power(n//p) + + raise NotImplementedError("is_nth_power() not implemented for this n") + + cdef FunctionFieldElement _pth_root(self): + r""" + Helper method for :meth:`nth_root` and :meth:`is_nth_power` which + computes a `p`-th root if the characteristic is `p` and the constant + base field is perfect. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: (y^3).nth_root(3) # indirect doctest # optional - sage.libs.pari + y + """ + cdef Py_ssize_t deg = self._parent.degree() + if deg == 1: + return self._parent(self._x[0].nth_root(self._parent.characteristic())) + + from .function_field import RationalFunctionField + if not isinstance(self.base_ring(), RationalFunctionField): + raise NotImplementedError("only implemented for simple extensions of function fields") + # compute a representation of the generator y of the field in terms of powers of y^p + cdef Py_ssize_t i + cdef list v = [] + char = self._parent.characteristic() + cdef FunctionFieldElement_polymod yp = self._parent.gen() ** char + val = self._parent.one()._x + poly = self._parent.polynomial() + for i in range(deg): + v += val.padded_list(deg) + val = (val * yp._x) % poly + from sage.matrix.matrix_space import MatrixSpace + MS = MatrixSpace(self._parent._base, deg) + M = MS(v) + y = self._parent._base.polynomial_ring()(M.solve_left(MS.column_space()([0,1]+[0]*(deg-2))).list()) + + f = self._x(y).map_coefficients(lambda c: c.nth_root(char)) + return self._parent(f) + + diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx new file mode 100644 index 00000000000..18d21e8dba2 --- /dev/null +++ b/src/sage/rings/function_field/element_rational.pyx @@ -0,0 +1,500 @@ + +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.richcmp cimport richcmp, richcmp_not_equal +from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element + +from sage.rings.function_field.element cimport FunctionFieldElement + + +cdef class FunctionFieldElement_rational(FunctionFieldElement): + """ + Elements of a rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); K + Rational function field in t over Rational Field + sage: t^2 + 3/2*t + t^2 + 3/2*t + sage: FunctionField(QQ,'t').gen()^3 + t^3 + """ + def __init__(self, parent, x, reduce=True): + """ + Initialize. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: x = t^3 + sage: TestSuite(x).run() + """ + FieldElement.__init__(self, parent) + self._x = x + + def __pari__(self): + r""" + Coerce the element to PARI. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: ((a+1)/(a-1)).__pari__() # optional - sage.libs.pari + (a + 1)/(a - 1) + + """ + return self.element().__pari__() + + def element(self): + """ + Return the underlying fraction field element that represents the element. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: t.element() # optional - sage.libs.pari + t + sage: type(t.element()) # optional - sage.libs.pari + <... 'sage.rings.fraction_field_FpT.FpTElement'> + + sage: K. = FunctionField(GF(131101)) # optional - sage.libs.pari + sage: t.element() # optional - sage.libs.pari + t + sage: type(t.element()) # optional - sage.libs.pari + <... 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'> + """ + return self._x + + cpdef list list(self): + """ + Return a list with just the element. + + The list represents the element when the rational function field is + viewed as a (one-dimensional) vector space over itself. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t.list() + [t] + """ + return [self] + + def _repr_(self): + """ + Return the string representation of the element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t._repr_() + 't' + """ + return repr(self._x) + + def __bool__(self): + """ + Return True if the element is not zero. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: bool(t) + True + sage: bool(K(0)) + False + sage: bool(K(1)) + True + """ + return not not self._x + + def __hash__(self): + """ + Return the hash of the element. + + TESTS: + + It would be nice if the following would produce a list of + 15 distinct hashes:: + + sage: K. = FunctionField(QQ) + sage: len({hash(t^i+t^j) for i in [-2..2] for j in [i..2]}) >= 10 + True + """ + return hash(self._x) + + cpdef _richcmp_(self, other, int op): + """ + Compare the element with the other element with respect to ``op`` + + INPUT: + + - ``other`` -- element + + - ``op`` -- comparison operator + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t > 0 + True + sage: t < t^2 + True + """ + cdef FunctionFieldElement left + cdef FunctionFieldElement right + try: + left = self + right = other + lp = left._parent + rp = right._parent + if lp != rp: + return richcmp_not_equal(lp, rp, op) + return richcmp(left._x, right._x, op) + except TypeError: + return NotImplemented + + cpdef _add_(self, right): + """ + Add the element with the other element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t + (3*t^3) # indirect doctest + 3*t^3 + t + """ + cdef FunctionFieldElement res = self._new_c() + res._x = self._x + (right)._x + return res + + cpdef _sub_(self, right): + """ + Subtract the other element from the element. + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t - (3*t^3) # indirect doctest + -3*t^3 + t + """ + cdef FunctionFieldElement res = self._new_c() + res._x = self._x - (right)._x + return res + + cpdef _mul_(self, right): + """ + Multiply the element with the other element + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: (t+1) * (t^2-1) # indirect doctest + t^3 + t^2 - t - 1 + """ + cdef FunctionFieldElement res = self._new_c() + res._x = self._x * (right)._x + return res + + cpdef _div_(self, right): + """ + Divide the element with the other element + + INPUT: + + - ``right`` -- element + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: (t+1) / (t^2 - 1) # indirect doctest + 1/(t - 1) + """ + cdef FunctionFieldElement res = self._new_c() + res._parent = self._parent.fraction_field() + res._x = self._x / (right)._x + return res + + def numerator(self): + """ + Return the numerator of the rational function. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: f = (t+1) / (t^2 - 1/3); f + (t + 1)/(t^2 - 1/3) + sage: f.numerator() + t + 1 + """ + return self._x.numerator() + + def denominator(self): + """ + Return the denominator of the rational function. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: f = (t+1) / (t^2 - 1/3); f + (t + 1)/(t^2 - 1/3) + sage: f.denominator() + t^2 - 1/3 + """ + return self._x.denominator() + + def valuation(self, place): + """ + Return the valuation of the rational function at the place. + + Rational function field places are associated with irreducible + polynomials. + + INPUT: + + - ``place`` -- a place or an irreducible polynomial + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: f = (t - 1)^2*(t + 1)/(t^2 - 1/3)^3 + sage: f.valuation(t - 1) + 2 + sage: f.valuation(t) + 0 + sage: f.valuation(t^2 - 1/3) + -3 + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: p = K.places_finite()[0] # optional - sage.libs.pari + sage: (1/x^2).valuation(p) # optional - sage.libs.pari + -2 + """ + from .place import FunctionFieldPlace + + if not isinstance(place, FunctionFieldPlace): + # place is an irreducible polynomial + R = self._parent._ring + return self._x.valuation(R(self._parent(place)._x)) + + prime = place.prime_ideal() + ideal = prime.ring().ideal(self) + return prime.valuation(ideal) + + def is_square(self): + """ + Return whether the element is a square. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: t.is_square() + False + sage: (t^2/4).is_square() + True + sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square() + True + + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: (-t^2).is_square() # optional - sage.libs.pari + True + sage: (-t^2).sqrt() # optional - sage.libs.pari + 2*t + """ + return self._x.is_square() + + def sqrt(self, all=False): + """ + Return the square root of the rational function. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: f = t^2 - 2 + 1/t^2; f.sqrt() + (t^2 - 1)/t + sage: f = t^2; f.sqrt(all=True) + [t, -t] + + TESTS:: + + sage: K(4/9).sqrt() + 2/3 + sage: K(0).sqrt(all=True) + [0] + """ + if all: + return [self._parent(r) for r in self._x.sqrt(all=True)] + else: + return self._parent(self._x.sqrt()) + + cpdef bint is_nth_power(self, n): + r""" + Return whether this element is an ``n``-th power in the rational + function field. + + INPUT: + + - ``n`` -- an integer + + OUTPUT: + + Returns ``True`` if there is an element `a` in the function field such + that this element equals `a^n`. + + ALGORITHM: + + If ``n`` is a power of the characteristic of the field and the constant + base field is perfect, then this uses the algorithm described in Lemma + 3 of [GiTr1996]_. + + .. SEEALSO:: + + :meth:`nth_root` + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: f = (x+1)/(x-1) # optional - sage.libs.pari + sage: f.is_nth_power(1) # optional - sage.libs.pari + True + sage: f.is_nth_power(3) # optional - sage.libs.pari + False + sage: (f^3).is_nth_power(3) # optional - sage.libs.pari + True + sage: (f^9).is_nth_power(-9) # optional - sage.libs.pari + True + """ + if n == 1: + return True + if n < 0: + return (~self).is_nth_power(-n) + + p = self._parent.characteristic() + if n == p: + return self._parent.derivation()(self).is_zero() + if p.divides(n): + return self.is_nth_power(p) and self.nth_root(p).is_nth_power(n//p) + if n == 2: + return self.is_square() + + raise NotImplementedError("is_nth_power() not implemented for the given n") + + cpdef FunctionFieldElement nth_root(self, n): + r""" + Return an ``n``-th root of this element in the function field. + + INPUT: + + - ``n`` -- an integer + + OUTPUT: + + Returns an element ``a`` in the rational function field such that this + element equals `a^n`. Raises an error if no such element exists. + + ALGORITHM: + + If ``n`` is a power of the characteristic of the field and the constant + base field is perfect, then this uses the algorithm described in + Corollary 3 of [GiTr1996]_. + + .. SEEALSO:: + + :meth:`is_nth_power` + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: f = (x+1)/(x+2) # optional - sage.libs.pari + sage: f.nth_root(1) # optional - sage.libs.pari + (x + 1)/(x + 2) + sage: f.nth_root(3) # optional - sage.libs.pari + Traceback (most recent call last): + ... + ValueError: element is not an n-th power + sage: (f^3).nth_root(3) # optional - sage.libs.pari + (x + 1)/(x + 2) + sage: (f^9).nth_root(-9) # optional - sage.libs.pari + (x + 2)/(x + 1) + """ + if n == 0: + if not self.is_one(): + raise ValueError("element is not a 0-th power") + return self + if n == 1: + return self + if n < 0: + return (~self).nth_root(-n) + p = self._parent.characteristic() + if p.divides(n): + if not self.is_nth_power(p): + raise ValueError("element is not an n-th power") + return self._parent(self.numerator().nth_root(p) / self.denominator().nth_root(p)).nth_root(n//p) + if n == 2: + return self.sqrt() + + raise NotImplementedError("nth_root() not implemented for {}".format(n)) + + def factor(self): + """ + Factor the rational function. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: f = (t+1) / (t^2 - 1/3) + sage: f.factor() # optional - sage.libs.pari + (t + 1) * (t^2 - 1/3)^-1 + sage: (7*f).factor() # optional - sage.libs.pari + (7) * (t + 1) * (t^2 - 1/3)^-1 + sage: ((7*f).factor()).unit() # optional - sage.libs.pari + 7 + sage: (f^3).factor() # optional - sage.libs.pari + (t + 1)^3 * (t^2 - 1/3)^-3 + """ + P = self.parent() + F = self._x.factor() + from sage.structure.factorization import Factorization + return Factorization([(P(a),e) for a,e in F], unit=F.unit()) + + def inverse_mod(self, I): + """ + Return an inverse of the element modulo the integral ideal `I`, if `I` + and the element together generate the unit ideal. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order(); I = O.ideal(x^2+1) + sage: t = O(x+1).inverse_mod(I); t + -1/2*x + 1/2 + sage: (t*(x+1) - 1) in I + True + + """ + assert len(I.gens()) == 1 + f = I.gens()[0]._x + assert f.denominator() == 1 + assert self._x.denominator() == 1 + return self.parent()(self._x.numerator().inverse_mod(f.numerator())) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py new file mode 100644 index 00000000000..a2cb0368f4a --- /dev/null +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -0,0 +1,2535 @@ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.arith.functions import lcm +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import LazyImport +from sage.rings.qqbar_decorators import handle_AA_and_QQbar +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.integer import Integer +from sage.categories.homset import Hom +from sage.categories.function_fields import FunctionFields + +from .element import FunctionFieldElement +from .element_polymod import FunctionFieldElement_polymod +from .function_field import FunctionField +from .function_field_rational import RationalFunctionField + + +class FunctionField_polymod(FunctionField): + """ + Function fields defined by a univariate polynomial, as an extension of the + base field. + + INPUT: + + - ``polynomial`` -- univariate polynomial over a function field + + - ``names`` -- tuple of length 1 or string; variable names + + - ``category`` -- category (default: category of function fields) + + EXAMPLES: + + We make a function field defined by a degree 5 polynomial over the + rational function field over the rational numbers:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + + We next make a function field over the above nontrivial function + field L:: + + sage: S. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 + y*z + y); M # optional - sage.libs.singular + Function field in z defined by z^2 + y*z + y + sage: 1/z # optional - sage.libs.singular + ((-x/(x^4 + 1))*y^4 + 2*x^2/(x^4 + 1))*z - 1 + sage: z * (1/z) # optional - sage.libs.singular + 1 + + We drill down the tower of function fields:: + + sage: M.base_field() # optional - sage.libs.singular + Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + sage: M.base_field().base_field() # optional - sage.libs.singular + Rational function field in x over Rational Field + sage: M.base_field().base_field().constant_field() # optional - sage.libs.singular + Rational Field + sage: M.constant_base_field() # optional - sage.libs.singular + Rational Field + + .. WARNING:: + + It is not checked if the polynomial used to define the function field is irreducible + Hence it is not guaranteed that this object really is a field! + This is illustrated below. + + :: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(x^2 - y^2) # optional - sage.libs.singular + sage: (y - x)*(y + x) # optional - sage.libs.singular + 0 + sage: 1/(y - x) # optional - sage.libs.singular + 1 + sage: y - x == 0; y + x == 0 # optional - sage.libs.singular + False + False + """ + Element = FunctionFieldElement_polymod + + def __init__(self, polynomial, names, category=None): + """ + Create a function field defined as an extension of another function + field by adjoining a root of a univariate polynomial. + + EXAMPLES: + + We create an extension of a function field:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular + Function field in y defined by y^5 + x*y - x^3 - 3*x + sage: TestSuite(L).run(max_runs=512) # long time (15s) # optional - sage.libs.singular + + We can set the variable name, which doesn't have to be y:: + + sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular + Function field in w defined by w^5 + x*w - x^3 - 3*x + + TESTS: + + Test that :trac:`17033` is fixed:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: M. = K.extension(x^7 - x - t) # optional - sage.libs.singular + sage: M(x) # optional - sage.libs.singular + z + sage: M('z') # optional - sage.libs.singular + z + sage: M('x') # optional - sage.libs.singular + Traceback (most recent call last): + ... + TypeError: unable to evaluate 'x' in Fraction Field of Univariate + Polynomial Ring in t over Rational Field + """ + from sage.rings.polynomial.polynomial_element import is_Polynomial + if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial): + raise TypeError("polynomial must be univariate a polynomial") + if names is None: + names = (polynomial.variable_name(), ) + elif names != polynomial.variable_name(): + polynomial = polynomial.change_variable_name(names) + if polynomial.degree() <= 0: + raise ValueError("polynomial must have positive degree") + base_field = polynomial.base_ring() + if not isinstance(base_field, FunctionField): + raise TypeError("polynomial must be over a FunctionField") + + self._base_field = base_field + self._polynomial = polynomial + + FunctionField.__init__(self, base_field, names=names, + category=FunctionFields().or_subcategory(category)) + + from .place_polymod import FunctionFieldPlace_polymod + self._place_class = FunctionFieldPlace_polymod + + self._hash = hash(polynomial) + self._ring = self._polynomial.parent() + + self._populate_coercion_lists_(coerce_list=[base_field, self._ring]) + self._gen = self(self._ring.gen()) + + def __hash__(self): + """ + Return hash of the function field. + + The hash value is equal to the hash of the defining polynomial. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L = K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular + sage: hash(L) == hash(L.polynomial()) # optional - sage.libs.singular + True + """ + return self._hash + + def _element_constructor_(self, x): + r""" + Make ``x`` into an element of the function field, possibly not canonically. + + INPUT: + + - ``x`` -- element + + TESTS:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L._element_constructor_(L.polynomial_ring().gen()) # optional - sage.libs.singular + y + """ + if isinstance(x, FunctionFieldElement): + return self.element_class(self, self._ring(x.element())) + return self.element_class(self, self._ring(x)) + + def gen(self, n=0): + """ + Return the `n`-th generator of the function field. By default, `n` is 0; any other + value of `n` leads to an error. The generator is the class of `y`, if we view + the function field as being presented as `K[y]/(f(y))`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.gen() # optional - sage.libs.singular + y + sage: L.gen(1) # optional - sage.libs.singular + Traceback (most recent call last): + ... + IndexError: there is only one generator + """ + if n != 0: + raise IndexError("there is only one generator") + return self._gen + + def ngens(self): + """ + Return the number of generators of the function field over its base + field. This is by definition 1. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.ngens() # optional - sage.libs.singular + 1 + """ + return 1 + + def _to_base_field(self, f): + r""" + Return ``f`` as an element of the :meth:`base_field`. + + INPUT: + + - ``f`` -- element of the function field which lies in the base + field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L._to_base_field(L(x)) # optional - sage.libs.singular + x + sage: L._to_base_field(y) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: y is not an element of the base field + + TESTS: + + Verify that :trac:`21872` has been resolved:: + + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + + sage: M(1) in QQ # optional - sage.libs.singular + True + sage: M(y) in L # optional - sage.libs.singular + True + sage: M(x) in K # optional - sage.libs.singular + True + sage: z in K # optional - sage.libs.singular + False + """ + K = self.base_field() + if f.element().is_constant(): + return K(f.element()) + raise ValueError("%r is not an element of the base field"%(f,)) + + def _to_constant_base_field(self, f): + """ + Return ``f`` as an element of the :meth:`constant_base_field`. + + INPUT: + + - ``f`` -- element of the rational function field which is a + constant + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L._to_constant_base_field(L(1)) # optional - sage.libs.singular + 1 + sage: L._to_constant_base_field(y) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: y is not an element of the base field + + TESTS: + + Verify that :trac:`21872` has been resolved:: + + sage: L(1) in QQ # optional - sage.libs.singular + True + sage: y in QQ # optional - sage.libs.singular + False + """ + return self.base_field()._to_constant_base_field(self._to_base_field(f)) + + def monic_integral_model(self, names=None): + """ + Return a function field isomorphic to this field but which is an + extension of a rational function field with defining polynomial that is + monic and integral over the constant base field. + + INPUT: + + - ``names`` -- a string or a tuple of up to two strings (default: + ``None``), the name of the generator of the field, and the name of + the generator of the underlying rational function field (if a tuple); + if not given, then the names are chosen automatically. + + OUTPUT: + + A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an + isomorphism from ``F`` to this field, and ``t`` is the inverse of + ``f``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular + Function field in y defined by x^2*y^5 - 1/x + sage: A, from_A, to_A = L.monic_integral_model('z') # optional - sage.libs.singular + sage: A # optional - sage.libs.singular + Function field in z defined by z^5 - x^12 + sage: from_A # optional - sage.libs.singular + Function Field morphism: + From: Function field in z defined by z^5 - x^12 + To: Function field in y defined by x^2*y^5 - 1/x + Defn: z |--> x^3*y + x |--> x + sage: to_A # optional - sage.libs.singular + Function Field morphism: + From: Function field in y defined by x^2*y^5 - 1/x + To: Function field in z defined by z^5 - x^12 + Defn: y |--> 1/x^3*z + x |--> x + sage: to_A(y) # optional - sage.libs.singular + 1/x^3*z + sage: from_A(to_A(y)) # optional - sage.libs.singular + y + sage: from_A(to_A(1/y)) # optional - sage.libs.singular + x^3*y^4 + sage: from_A(to_A(1/y)) == 1/y # optional - sage.libs.singular + True + + This also works for towers of function fields:: + + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2*y - 1/x) # optional - sage.libs.singular + sage: M.monic_integral_model() # optional - sage.libs.singular + (Function field in z_ defined by z_^10 - x^18, + Function Field morphism: + From: Function field in z_ defined by z_^10 - x^18 + To: Function field in z defined by y*z^2 - 1/x + Defn: z_ |--> x^2*z + x |--> x, Function Field morphism: + From: Function field in z defined by y*z^2 - 1/x + To: Function field in z_ defined by z_^10 - x^18 + Defn: z |--> 1/x^2*z_ + y |--> 1/x^15*z_^8 + x |--> x) + + TESTS: + + If the field is already a monic integral extension, then it is returned + unchanged:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: L.monic_integral_model() # optional - sage.libs.singular + (Function field in y defined by y^2 - x, + Function Field endomorphism of Function field in y defined by y^2 - x + Defn: y |--> y + x |--> x, Function Field endomorphism of Function field in y defined by y^2 - x + Defn: y |--> y + x |--> x) + + unless ``names`` does not match with the current names:: + + sage: L.monic_integral_model(names=('yy','xx')) # optional - sage.libs.singular + (Function field in yy defined by yy^2 - xx, + Function Field morphism: + From: Function field in yy defined by yy^2 - xx + To: Function field in y defined by y^2 - x + Defn: yy |--> y + xx |--> x, Function Field morphism: + From: Function field in y defined by y^2 - x + To: Function field in yy defined by yy^2 - xx + Defn: y |--> yy + x |--> xx) + + """ + if names: + if not isinstance(names, tuple): + names = (names,) + if len(names) > 2: + raise ValueError("names must contain at most 2 entries") + + if self.base_field() is not self.rational_function_field(): + L,from_L,to_L = self.simple_model() + ret,ret_to_L,L_to_ret = L.monic_integral_model(names) + from_ret = ret.hom( [from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))] ) + to_ret = self.hom( [L_to_ret(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())] ) + return ret, from_ret, to_ret + else: + if self.polynomial().is_monic() and all(c.denominator().is_one() for c in self.polynomial()): + # self is already monic and integral + if names is None or names == (): + names = (self.variable_name(),) + return self.change_variable_name(names) + else: + if not names: + names = (self.variable_name()+"_",) + if len(names) == 1: + names = (names[0], self.rational_function_field().variable_name()) + + g, d = self._make_monic_integral(self.polynomial()) + K,from_K,to_K = self.base_field().change_variable_name(names[1]) + g = g.map_coefficients(to_K) + ret = K.extension(g, names=names[0]) + from_ret = ret.hom([self.gen() * d, self.base_field().gen()]) + to_ret = self.hom([ret.gen() / d, ret.base_field().gen()]) + return ret, from_ret, to_ret + + def _make_monic_integral(self, f): + """ + Return a monic integral polynomial `g` and an element `d` of the base + field such that `g(y*d)=0` where `y` is a root of `f`. + + INPUT: + + - ``f`` -- polynomial + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(x^2*y^5 - 1/x) # optional - sage.libs.singular + sage: g, d = L._make_monic_integral(L.polynomial()); g,d # optional - sage.libs.singular + (y^5 - x^12, x^3) + sage: (y*d).is_integral() # optional - sage.libs.singular + True + sage: g.is_monic() # optional - sage.libs.singular + True + sage: g(y*d) # optional - sage.libs.singular + 0 + """ + R = f.base_ring() + if not isinstance(R, RationalFunctionField): + raise NotImplementedError + + # make f monic + n = f.degree() + c = f.leading_coefficient() + if c != 1: + f = f / c + + # find lcm of denominators + # would be good to replace this by minimal... + d = lcm([b.denominator() for b in f.list() if b]) + if d != 1: + x = f.parent().gen() + g = (d**n) * f(x/d) + else: + g = f + return g, d + + def constant_field(self): + """ + Return the algebraic closure of the constant field of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^5 - x) # optional - sage.libs.pari + sage: L.constant_field() # optional - sage.libs.pari + Traceback (most recent call last): + ... + NotImplementedError + """ + raise NotImplementedError + + def constant_base_field(self): + """ + Return the base constant field of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + sage: L.constant_base_field() # optional - sage.libs.singular + Rational Field + sage: S. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.constant_base_field() # optional - sage.libs.singular + Rational Field + """ + return self.base_field().constant_base_field() + + @cached_method(key=lambda self, base: self.base_field() if base is None else base) + def degree(self, base=None): + """ + Return the degree of the function field over the function field ``base``. + + INPUT: + + - ``base`` -- a function field (default: ``None``), a function field + from which this field has been constructed as a finite extension. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + sage: L.degree() # optional - sage.libs.singular + 5 + sage: L.degree(L) # optional - sage.libs.singular + 1 + + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.degree(L) # optional - sage.libs.singular + 2 + sage: M.degree(K) # optional - sage.libs.singular + 10 + + TESTS:: + + sage: L.degree(M) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: base must be the rational function field itself + + """ + if base is None: + base = self.base_field() + if base is self: + from sage.rings.integer_ring import ZZ + return ZZ(1) + return self._polynomial.degree() * self.base_field().degree(base) + + def _repr_(self): + """ + Return the string representation of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L._repr_() # optional - sage.libs.singular + 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' + """ + return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial) + + def base_field(self): + """ + Return the base field of the function field. This function field is + presented as `L = K[y]/(f(y))`, and the base field is by definition the + field `K`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.base_field() # optional - sage.libs.singular + Rational function field in x over Rational Field + """ + return self._base_field + + def random_element(self, *args, **kwds): + """ + Create a random element of the function field. Parameters are passed + onto the random_element method of the base_field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x)) # optional - sage.libs.singular + sage: L.random_element() # random # optional - sage.libs.singular + ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y + + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95) + """ + return self(self._ring.random_element(degree=self.degree(), *args, **kwds)) + + def polynomial(self): + """ + Return the univariate polynomial that defines the function field, that + is, the polynomial `f(y)` so that the function field is of the form + `K[y]/(f(y))`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.polynomial() # optional - sage.libs.singular + y^5 - 2*x*y + (-x^4 - 1)/x + """ + return self._polynomial + + def is_separable(self, base=None): + r""" + Return whether this is a separable extension of ``base``. + + INPUT: + + - ``base`` -- a function field from which this field has been created + as an extension or ``None`` (default: ``None``); if ``None``, then + return whether this is a separable extension over its base field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari + False + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari + sage: M.is_separable() # optional - sage.libs.pari + True + sage: M.is_separable(K) # optional - sage.libs.pari + False + + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari + True + + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - 1) # optional - sage.libs.pari + sage: L.is_separable() # optional - sage.libs.pari + False + + """ + if base is None: + base = self.base_field() + for k in self._intermediate_fields(base)[:-1]: + f = k.polynomial() + g = f.derivative() + if f.gcd(g).degree() != 0: + return False + return True + + def polynomial_ring(self): + """ + Return the polynomial ring used to represent elements of the + function field. If we view the function field as being presented + as `K[y]/(f(y))`, then this function returns the ring `K[y]`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.polynomial_ring() # optional - sage.libs.singular + Univariate Polynomial Ring in y over Rational function field in x over Rational Field + """ + return self._ring + + @cached_method(key=lambda self, base, basis, map: (self.base_field() if base is None else base, basis, map)) + def free_module(self, base=None, basis=None, map=True): + """ + Return a vector space and isomorphisms from the field to and from the + vector space. + + This function allows us to identify the elements of this field with + elements of a vector space over the base field, which is useful for + representation and arithmetic with orders, ideals, etc. + + INPUT: + + - ``base`` -- a function field (default: ``None``), the returned vector + space is over this subfield `R`, which defaults to the base field of this + function field. + + - ``basis`` -- a basis for this field over the base. + + - ``maps`` -- boolean (default ``True``), whether to return + `R`-linear maps to and from `V`. + + OUTPUT: + + - a vector space over the base function field + + - an isomorphism from the vector space to the field (if requested) + + - an isomorphism from the field to the vector space (if requested) + + EXAMPLES: + + We define a function field:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + + We get the vector spaces, and maps back and forth:: + + sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular sage.modules + sage: V # optional - sage.libs.singular sage.modules + Vector space of dimension 5 over Rational function field in x over Rational Field + sage: from_V # optional - sage.libs.singular sage.modules + Isomorphism: + From: Vector space of dimension 5 over Rational function field in x over Rational Field + To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + sage: to_V # optional - sage.libs.singular sage.modules + Isomorphism: + From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + To: Vector space of dimension 5 over Rational function field in x over Rational Field + + We convert an element of the vector space back to the function field:: + + sage: from_V(V.1) # optional - sage.libs.singular sage.modules + y + + We define an interesting element of the function field:: + + sage: a = 1/L.0; a # optional - sage.libs.singular sage.modules + (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1) + + We convert it to the vector space, and get a vector over the base field:: + + sage: to_V(a) # optional - sage.libs.singular sage.modules + (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1)) + + We convert to and back, and get the same element:: + + sage: from_V(to_V(a)) == a # optional - sage.libs.singular sage.modules + True + + In the other direction:: + + sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular sage.modules + sage: to_V(from_V(v)) == v # optional - sage.libs.singular sage.modules + True + + And we show how it works over an extension of an extension field:: + + sage: R2. = L[]; M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M.free_module() # optional - sage.libs.singular sage.modules + (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism: + From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + To: Function field in z defined by z^2 - y, Isomorphism: + From: Function field in z defined by z^2 - y + To: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x) + + We can also get the vector space of ``M`` over ``K``:: + + sage: M.free_module(K) # optional - sage.libs.singular sage.modules + (Vector space of dimension 10 over Rational function field in x over Rational Field, Isomorphism: + From: Vector space of dimension 10 over Rational function field in x over Rational Field + To: Function field in z defined by z^2 - y, Isomorphism: + From: Function field in z defined by z^2 - y + To: Vector space of dimension 10 over Rational function field in x over Rational Field) + + """ + if basis is not None: + raise NotImplementedError + from .maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace + if base is None: + base = self.base_field() + degree = self.degree(base) + V = base**degree + if not map: + return V + from_V = MapVectorSpaceToFunctionField(V, self) + to_V = MapFunctionFieldToVectorSpace(self, V) + return (V, from_V, to_V) + + def maximal_order(self): + """ + Return the maximal order of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.maximal_order() # optional - sage.libs.singular + Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + """ + from .order import FunctionFieldMaximalOrder_polymod + return FunctionFieldMaximalOrder_polymod(self) + + def maximal_order_infinite(self): + """ + Return the maximal infinite order of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.maximal_order_infinite() # optional - sage.libs.singular + Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari + Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: L.maximal_order_infinite() # optional - sage.libs.pari + Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + from .order import FunctionFieldMaximalOrderInfinite_polymod + return FunctionFieldMaximalOrderInfinite_polymod(self) + + def different(self): + """ + Return the different of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F.different() # optional - sage.libs.pari + 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) + """ + O = self.maximal_order() + Oinf = self.maximal_order_infinite() + return O.different().divisor() + Oinf.different().divisor() + + def equation_order(self): + """ + Return the equation order of the function field. + + If we view the function field as being presented as `K[y]/(f(y))`, then + the order generated by the class of `y` is returned. If `f` + is not monic, then :meth:`_make_monic_integral` is called, and instead + we get the order generated by some integral multiple of a root of `f`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.basis() # optional - sage.libs.singular + (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4) + + We try an example, in which the defining polynomial is not + monic and is not integral:: + + sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular + sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular + Function field in y defined by x^2*y^5 - 1/x + sage: O = L.equation_order() # optional - sage.libs.singular + sage: O.basis() # optional - sage.libs.singular + (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4) + """ + d = self._make_monic_integral(self.polynomial())[1] + return self.order(d*self.gen(), check=False) + + def hom(self, im_gens, base_morphism=None): + """ + Create a homomorphism from the function field to another function field. + + INPUT: + + - ``im_gens`` -- list of images of the generators of the function field + and of successive base rings. + + - ``base_morphism`` -- homomorphism of the base ring, after the + ``im_gens`` are used. Thus if ``im_gens`` has length 2, then + ``base_morphism`` should be a morphism from the base ring of the base + ring of the function field. + + EXAMPLES: + + We create a rational function field, and a quadratic extension of it:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + + We make the field automorphism that sends y to -y:: + + sage: f = L.hom(-y); f # optional - sage.libs.singular + Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 + Defn: y |--> -y + + Evaluation works:: + + sage: f(y*x - 1/x) # optional - sage.libs.singular + -x*y - 1/x + + We try to define an invalid morphism:: + + sage: f = L.hom(y + 1) # optional - sage.libs.singular + Traceback (most recent call last): + ... + ValueError: invalid morphism + + We make a morphism of the base rational function field:: + + sage: phi = K.hom(x + 1); phi # optional - sage.libs.singular + Function Field endomorphism of Rational function field in x over Rational Field + Defn: x |--> x + 1 + sage: phi(x^3 - 3) # optional - sage.libs.singular + x^3 + 3*x^2 + 3*x - 2 + sage: (x+1)^3 - 3 # optional - sage.libs.singular + x^3 + 3*x^2 + 3*x - 2 + + We make a morphism by specifying where the generators and the + base generators go:: + + sage: L.hom([-y, x]) # optional - sage.libs.singular + Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 + Defn: y |--> -y + x |--> x + + You can also specify a morphism on the base:: + + sage: R1. = K[] + sage: L1. = K.extension(q^2 - (x+1)^3 - 1) # optional - sage.libs.singular + sage: L.hom(q, base_morphism=phi) # optional - sage.libs.singular + Function Field morphism: + From: Function field in y defined by y^2 - x^3 - 1 + To: Function field in q defined by q^2 - x^3 - 3*x^2 - 3*x - 2 + Defn: y |--> q + x |--> x + 1 + + We make another extension of a rational function field:: + + sage: K2. = FunctionField(QQ); R2. = K2[] + sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) # optional - sage.libs.singular + + We define a morphism, by giving the images of generators:: + + sage: f = L.hom([4*w, t + 1]); f # optional - sage.libs.singular + Function Field morphism: + From: Function field in y defined by y^2 - x^3 - 1 + To: Function field in w defined by 16*w^2 - t^3 - 3*t^2 - 3*t - 2 + Defn: y |--> 4*w + x |--> t + 1 + + Evaluation works, as expected:: + + sage: f(y+x) # optional - sage.libs.singular + 4*w + t + 1 + sage: f(x*y + x/(x^2+1)) # optional - sage.libs.singular + (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2) + + We make another extension of a rational function field:: + + sage: K3. = FunctionField(QQ); R3. = K3[] + sage: L3. = K3.extension(yy^2 - xx^3 - 1) # optional - sage.libs.singular + + This is the function field L with the generators exchanged. We define a morphism to L:: + + sage: g = L3.hom([x,y]); g # optional - sage.libs.singular + Function Field morphism: + From: Function field in xx defined by -xx^3 + yy^2 - 1 + To: Function field in y defined by y^2 - x^3 - 1 + Defn: xx |--> x + yy |--> y + + """ + if not isinstance(im_gens, (list,tuple)): + im_gens = [im_gens] + if len(im_gens) == 0: + raise ValueError("no images specified") + + if len(im_gens) > 1: + base_morphism = self.base_field().hom(im_gens[1:], base_morphism) + + # the codomain of this morphism is the field containing all the im_gens + codomain = im_gens[0].parent() + if base_morphism is not None: + from sage.categories.pushout import pushout + codomain = pushout(codomain, base_morphism.codomain()) + + from .maps import FunctionFieldMorphism_polymod + return FunctionFieldMorphism_polymod(self.Hom(codomain), im_gens[0], base_morphism) + + @cached_method + def genus(self): + """ + Return the genus of the function field. + + For now, the genus is computed using Singular. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular + sage: L.genus() # optional - sage.libs.singular + 3 + """ + # Unfortunately Singular can not compute the genus with the + # polynomial_ring()._singular_ object because genus method only accepts + # a ring of transcendental degree 2 over a prime field not a ring of + # transcendental degree 1 over a rational function field of one variable + + if (isinstance(self._base_field, RationalFunctionField) and + self._base_field.constant_field().is_prime_field()): + from sage.interfaces.singular import singular + + # making the auxiliary ring which only has polynomials + # with integral coefficients. + tmpAuxRing = PolynomialRing(self._base_field.constant_field(), + str(self._base_field.gen())+','+str(self._ring.gen())) + intMinPoly, d = self._make_monic_integral(self._polynomial) + curveIdeal = tmpAuxRing.ideal(intMinPoly) + + singular.lib('normal.lib') #loading genus method in Singular + return int(curveIdeal._singular_().genus()) + + else: + raise NotImplementedError("computation of genus over non-prime " + "constant fields not implemented yet") + + def _simple_model(self, name='v'): + r""" + Return a finite extension `N/K(x)` isomorphic to the tower of + extensions `M/L/K(x)` with `K` perfect. + + Helper method for :meth:`simple_model`. + + INPUT: + + - ``name`` -- a string, the name of the generator of `N` + + ALGORITHM: + + Since `K` is perfect, the extension `M/K(x)` is simple, i.e., generated + by a single element [BM1940]_. Therefore, there are only finitely many + intermediate fields (Exercise 3.6.7 in [Bo2009]_). + Let `a` be a generator of `M/L` and let `b` be a generator of `L/K(x)`. + For some `i` the field `N_i=K(x)(a+x^ib)` is isomorphic to `M` and so + it is enough to test for all terms of the form `a+x^ib` whether they + generate a field of the right degree. + Indeed, suppose for contradiction that for all `i` we had `N_i\neq M`. + Then `N_i=N_j` for some `i,j`. Thus `(a+x^ib)-(a+x^jb)=b(x^i-x^j)\in + N_j` and so `b\in N_j`. Similarly, + `a+x^ib-x^{i-j}(a+x^jb)=a(1+x^{i-j})\in N_j` and so `a\in N_j`. + Therefore, `N_j=M`. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: M._simple_model() # optional - sage.libs.singular + (Function field in v defined by v^4 - x, + Function Field morphism: + From: Function field in v defined by v^4 - x + To: Function field in z defined by z^2 - y + Defn: v |--> z, + Function Field morphism: + From: Function field in z defined by z^2 - y + To: Function field in v defined by v^4 - x + Defn: z |--> v + y |--> v^2) + + Check that this also works for inseparable extensions:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: M._simple_model() # optional - sage.libs.pari + (Function field in v defined by v^4 + x, + Function Field morphism: + From: Function field in v defined by v^4 + x + To: Function field in z defined by z^2 + y + Defn: v |--> z, + Function Field morphism: + From: Function field in z defined by z^2 + y + To: Function field in v defined by v^4 + x + Defn: z |--> v + y |--> v^2) + + An example where the generator of the last extension does not generate + the extension of the rational function field:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - 1) # optional - sage.libs.pari + sage: M._simple_model() # optional - sage.libs.pari + (Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1, + Function Field morphism: + From: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 + To: Function field in z defined by z^3 + 1 + Defn: v |--> z + y, + Function Field morphism: + From: Function field in z defined by z^3 + 1 + To: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 + Defn: z |--> v^4 + x^2 + y |--> v^4 + v + x^2) + + """ + M = self + L = M.base_field() + K = L.base_field() + + assert(isinstance(K, RationalFunctionField)) + assert(K is not L) + assert(L is not M) + + if not K.constant_field().is_perfect(): + raise NotImplementedError("simple_model() only implemented over perfect constant fields") + + x = K.gen() + b = L.gen() + a = M.gen() + + # using a+x^i*b tends to lead to huge powers of x in the minimal + # polynomial of the resulting field; it is better to try terms of + # the form a+i*b first (but in characteristic p>0 there are only + # finitely many of these) + # We systematically try elements of the form a+b*factor*x^exponent + factor = self.constant_base_field().zero() + exponent = 0 + while True: + v = M(a+b*factor*x**exponent) + minpoly = v.matrix(K).minpoly() + if minpoly.degree() == M.degree()*L.degree(): + break + factor += 1 + if factor == 0: + factor = self.constant_base_field().one() + exponent += 1 + + N = K.extension(minpoly, names=(name,)) + + # the morphism N -> M, v |-> v + N_to_M = N.hom(v) + + # the morphism M -> N, b |-> M_b, a |-> M_a + V, V_to_M, M_to_V = M.free_module(K) + V, V_to_N, N_to_V = N.free_module(K) + from sage.matrix.matrix_space import MatrixSpace + MS = MatrixSpace(V.base_field(), V.dimension()) + # the power basis of v over K + B = [M_to_V(v**i) for i in range(V.dimension())] + B = MS(B) + M_b = V_to_N(B.solve_left(M_to_V(b))) + M_a = V_to_N(B.solve_left(M_to_V(a))) + M_to_N = M.hom([M_a,M_b]) + + return N, N_to_M, M_to_N + + @cached_method + def simple_model(self, name=None): + """ + Return a function field isomorphic to this field which is a simple + extension of a rational function field. + + INPUT: + + - ``name`` -- a string (default: ``None``), the name of generator of + the simple extension. If ``None``, then the name of the generator + will be the same as the name of the generator of this function field. + + OUTPUT: + + A triple ``(F,f,t)`` where ``F`` is a field isomorphic to this field, + ``f`` is an isomorphism from ``F`` to this function field and ``t`` is + the inverse of ``f``. + + EXAMPLES: + + A tower of four function fields:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(z^2 - x); R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(u^2 - z); R. = M[] # optional - sage.libs.singular + sage: N. = M.extension(v^2 - u) # optional - sage.libs.singular + + The fields N and M as simple extensions of K:: + + sage: N.simple_model() # optional - sage.libs.singular + (Function field in v defined by v^8 - x, + Function Field morphism: + From: Function field in v defined by v^8 - x + To: Function field in v defined by v^2 - u + Defn: v |--> v, + Function Field morphism: + From: Function field in v defined by v^2 - u + To: Function field in v defined by v^8 - x + Defn: v |--> v + u |--> v^2 + z |--> v^4 + x |--> x) + sage: M.simple_model() # optional - sage.libs.singular + (Function field in u defined by u^4 - x, + Function Field morphism: + From: Function field in u defined by u^4 - x + To: Function field in u defined by u^2 - z + Defn: u |--> u, + Function Field morphism: + From: Function field in u defined by u^2 - z + To: Function field in u defined by u^4 - x + Defn: u |--> u + z |--> u^2 + x |--> x) + + An optional parameter ``name`` can be used to set the name of the + generator of the simple extension:: + + sage: M.simple_model(name='t') # optional - sage.libs.singular + (Function field in t defined by t^4 - x, Function Field morphism: + From: Function field in t defined by t^4 - x + To: Function field in u defined by u^2 - z + Defn: t |--> u, Function Field morphism: + From: Function field in u defined by u^2 - z + To: Function field in t defined by t^4 - x + Defn: u |--> t + z |--> t^2 + x |--> x) + + An example with higher degrees:: + + sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5-x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3-x) # optional - sage.libs.pari + sage: M.simple_model() # optional - sage.libs.pari + (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3, + Function Field morphism: + From: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 + To: Function field in z defined by z^3 + 2*x + Defn: z |--> z + y, + Function Field morphism: + From: Function field in z defined by z^3 + 2*x + To: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 + Defn: z |--> 2/x*z^6 + 2*z^3 + z + 2*x + y |--> 1/x*z^6 + z^3 + x + x |--> x) + + This also works for inseparable extensions:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2-x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2-y) # optional - sage.libs.pari + sage: M.simple_model() # optional - sage.libs.pari + (Function field in z defined by z^4 + x, Function Field morphism: + From: Function field in z defined by z^4 + x + To: Function field in z defined by z^2 + y + Defn: z |--> z, Function Field morphism: + From: Function field in z defined by z^2 + y + To: Function field in z defined by z^4 + x + Defn: z |--> z + y |--> z^2 + x |--> x) + """ + if name is None: + name = self.variable_name() + + if isinstance(self.base_field(), RationalFunctionField): + # the extension is simple already + if name == self.variable_name(): + id = Hom(self,self).identity() + return self, id, id + else: + ret = self.base_field().extension(self.polynomial(), names=(name,)) + f = ret.hom(self.gen()) + t = self.hom(ret.gen()) + return ret, f, t + else: + # recursively collapse the tower of fields + base = self.base_field() + base_, from_base_, to_base_ = base.simple_model() + self_ = base_.extension(self.polynomial().map_coefficients(to_base_), names=(name,)) + gens_in_base_ = [to_base_(k.gen()) + for k in base._intermediate_fields(base.rational_function_field())] + to_self_ = self.hom([self_.gen()]+gens_in_base_) + from_self_ = self_.hom([self.gen(),from_base_(base_.gen())]) + + # now collapse self_/base_/K(x) + ret, ret_to_self_, self__to_ret = self_._simple_model(name) + ret_to_self = ret.hom(from_self_(ret_to_self_(ret.gen()))) + gens_in_ret = [self__to_ret(to_self_(k.gen())) + for k in self._intermediate_fields(self.rational_function_field())] + self_to_ret = self.hom(gens_in_ret) + return ret, ret_to_self, self_to_ret + + @cached_method + def primitive_element(self): + r""" + Return a primitive element over the underlying rational function field. + + If this is a finite extension of a rational function field `K(x)` with + `K` perfect, then this is a simple extension of `K(x)`, i.e., there is + a primitive element `y` which generates this field over `K(x)`. This + method returns such an element `y`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: N. = L.extension(z^2 - x - 1) # optional - sage.libs.singular + sage: N.primitive_element() # optional - sage.libs.singular + u + y + sage: M.primitive_element() # optional - sage.libs.singular + z + sage: L.primitive_element() # optional - sage.libs.singular + y + + This also works for inseparable extensions:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2-x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(Z^2-y) # optional - sage.libs.pari + sage: M.primitive_element() # optional - sage.libs.pari + z + """ + N, f, t = self.simple_model() + return f(N.gen()) + + @cached_method + def separable_model(self, names=None): + r""" + Return a function field isomorphic to this field which is a separable + extension of a rational function field. + + INPUT: + + - ``names`` -- a tuple of two strings or ``None`` (default: ``None``); + the second entry will be used as the variable name of the rational + function field, the first entry will be used as the variable name of + its separable extension. If ``None``, then the variable names will be + chosen automatically. + + OUTPUT: + + A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an + isomorphism from ``F`` to this function field, and ``t`` is the inverse + of ``f``. + + ALGORITHM: + + Suppose that the constant base field is perfect. If this is a monic + integral inseparable extension of a rational function field, then the + defining polynomial is separable if we swap the variables (Proposition + 4.8 in Chapter VIII of [Lan2002]_.) + The algorithm reduces to this case with :meth:`monic_integral_model`. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.pari + sage: L.separable_model(('t','w')) # optional - sage.libs.pari + (Function field in t defined by t^3 + w^2, + Function Field morphism: + From: Function field in t defined by t^3 + w^2 + To: Function field in y defined by y^2 + x^3 + Defn: t |--> x + w |--> y, + Function Field morphism: + From: Function field in y defined by y^2 + x^3 + To: Function field in t defined by t^3 + w^2 + Defn: y |--> w + x |--> t) + + This also works for non-integral polynomials:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2/x - x^2) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari + (Function field in y_ defined by y_^3 + x_^2, + Function Field morphism: + From: Function field in y_ defined by y_^3 + x_^2 + To: Function field in y defined by 1/x*y^2 + x^2 + Defn: y_ |--> x + x_ |--> y, + Function Field morphism: + From: Function field in y defined by 1/x*y^2 + x^2 + To: Function field in y_ defined by y_^3 + x_^2 + Defn: y |--> x_ + x |--> y_) + + If the base field is not perfect this is only implemented in trivial cases:: + + sage: k. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: k.is_perfect() # optional - sage.libs.pari + False + sage: K. = FunctionField(k) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 - t) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari + (Function field in y defined by y^3 + t, + Function Field endomorphism of Function field in y defined by y^3 + t + Defn: y |--> y + x |--> x, + Function Field endomorphism of Function field in y defined by y^3 + t + Defn: y |--> y + x |--> x) + + Some other cases for which a separable model could be constructed are + not supported yet:: + + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - t) # optional - sage.libs.pari + sage: L.separable_model() # optional - sage.libs.pari + Traceback (most recent call last): + ... + NotImplementedError: constructing a separable model is only implemented for function fields over a perfect constant base field + + TESTS: + + Check that this also works in characteristic zero:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.singular + sage: L.separable_model() # optional - sage.libs.singular + (Function field in y defined by y^2 - x^3, + Function Field endomorphism of Function field in y defined by y^2 - x^3 + Defn: y |--> y + x |--> x, + Function Field endomorphism of Function field in y defined by y^2 - x^3 + Defn: y |--> y + x |--> x) + + Check that this works for towers of inseparable extensions:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: M.separable_model() # optional - sage.libs.pari + (Function field in z_ defined by z_ + x_^4, + Function Field morphism: + From: Function field in z_ defined by z_ + x_^4 + To: Function field in z defined by z^2 + y + Defn: z_ |--> x + x_ |--> z, + Function Field morphism: + From: Function field in z defined by z^2 + y + To: Function field in z_ defined by z_ + x_^4 + Defn: z |--> x_ + y |--> x_^2 + x |--> x_^4) + + Check that this also works if only the first extension is inseparable:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari + sage: M.separable_model() # optional - sage.libs.pari + (Function field in z_ defined by z_ + x_^6, Function Field morphism: + From: Function field in z_ defined by z_ + x_^6 + To: Function field in z defined by z^3 + y + Defn: z_ |--> x + x_ |--> z, Function Field morphism: + From: Function field in z defined by z^3 + y + To: Function field in z_ defined by z_ + x_^6 + Defn: z |--> x_ + y |--> x_^3 + x |--> x_^6) + + """ + if names is None: + pass + elif not isinstance(names, tuple): + raise TypeError("names must be a tuple consisting of two strings") + elif len(names) != 2: + raise ValueError("must provide exactly two variable names") + + if self.base_ring() is not self.rational_function_field(): + L, from_L, to_L = self.simple_model() + K, from_K, to_K = L.separable_model(names=names) + f = K.hom([from_L(from_K(K.gen())), from_L(from_K(K.base_field().gen()))]) + t = self.hom([to_K(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())]) + return K, f, t + + if self.polynomial().gcd(self.polynomial().derivative()).is_one(): + # the model is already separable + if names is None: + names = self.variable_name(), self.base_field().variable_name() + return self.change_variable_name(names) + + if not self.constant_base_field().is_perfect(): + raise NotImplementedError("constructing a separable model is only implemented for function fields over a perfect constant base field") + + if names is None: + names = (self.variable_name()+"_", self.rational_function_field().variable_name()+"_") + + L, from_L, to_L = self.monic_integral_model() + + if L.polynomial().gcd(L.polynomial().derivative()).is_one(): + # L is separable + ret, ret_to_L, L_to_ret = L.change_variable_name(names) + f = ret.hom([from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))]) + t = self.hom([L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))]) + return ret, f, t + else: + # otherwise, the polynomial of L must be separable in the other variable + from .constructor import FunctionField + K = FunctionField(self.constant_base_field(), names=(names[1],)) + # construct a field isomorphic to L on top of K + + # turn the minpoly of K into a bivariate polynomial + if names[0] == names[1]: + raise ValueError("names of generators must be distinct") + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self.constant_base_field(), names=names) + S = R.remove_var(names[1]) + f = R( L.polynomial().change_variable_name(names[1]).map_coefficients( + lambda c:c.numerator().change_variable_name(names[0]), S)) + f = f.polynomial(R.gen(0)).change_ring(K) + f /= f.leading_coefficient() + # f must be separable in the other variable (otherwise it would factor) + assert f.gcd(f.derivative()).is_one() + + ret = K.extension(f, names=(names[0],)) + # isomorphisms between L and ret are given by swapping generators + ret_to_L = ret.hom( [L(L.base_field().gen()), L.gen()] ) + L_to_ret = L.hom( [ret(K.gen()), ret.gen()] ) + # compose with from_L and to_L to get the desired isomorphisms between self and ret + f = ret.hom( [from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))] ) + t = self.hom( [L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))] ) + return ret, f, t + + def change_variable_name(self, name): + r""" + Return a field isomorphic to this field with variable(s) ``name``. + + INPUT: + + - ``name`` -- a string or a tuple consisting of a strings, the names of + the new variables starting with a generator of this field and going + down to the rational function field. + + OUTPUT: + + A triple ``F,f,t`` where ``F`` is a function field, ``f`` is an + isomorphism from ``F`` to this field, and ``t`` is the inverse of + ``f``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + + sage: M.change_variable_name('zz') # optional - sage.libs.singular + (Function field in zz defined by zz^2 - y, + Function Field morphism: + From: Function field in zz defined by zz^2 - y + To: Function field in z defined by z^2 - y + Defn: zz |--> z + y |--> y + x |--> x, + Function Field morphism: + From: Function field in z defined by z^2 - y + To: Function field in zz defined by zz^2 - y + Defn: z |--> zz + y |--> y + x |--> x) + sage: M.change_variable_name(('zz','yy')) # optional - sage.libs.singular + (Function field in zz defined by zz^2 - yy, Function Field morphism: + From: Function field in zz defined by zz^2 - yy + To: Function field in z defined by z^2 - y + Defn: zz |--> z + yy |--> y + x |--> x, Function Field morphism: + From: Function field in z defined by z^2 - y + To: Function field in zz defined by zz^2 - yy + Defn: z |--> zz + y |--> yy + x |--> x) + sage: M.change_variable_name(('zz','yy','xx')) # optional - sage.libs.singular + (Function field in zz defined by zz^2 - yy, + Function Field morphism: + From: Function field in zz defined by zz^2 - yy + To: Function field in z defined by z^2 - y + Defn: zz |--> z + yy |--> y + xx |--> x, + Function Field morphism: + From: Function field in z defined by z^2 - y + To: Function field in zz defined by zz^2 - yy + Defn: z |--> zz + y |--> yy + x |--> xx) + + """ + if not isinstance(name, tuple): + name = (name,) + if len(name) == 0: + raise ValueError("name must contain at least one string") + elif len(name) == 1: + base = self.base_field() + from_base = to_base = Hom(base,base).identity() + else: + base, from_base, to_base = self.base_field().change_variable_name(name[1:]) + + ret = base.extension(self.polynomial().map_coefficients(to_base), names=(name[0],)) + f = ret.hom( [k.gen() for k in self._intermediate_fields(self.rational_function_field())] ) + t = self.hom( [k.gen() for k in ret._intermediate_fields(ret.rational_function_field())] ) + return ret, f, t + + +class FunctionField_simple(FunctionField_polymod): + """ + Function fields defined by irreducible and separable polynomials + over rational function fields. + """ + @cached_method + def _inversion_isomorphism(self): + r""" + Return an inverted function field isomorphic to ``self`` and isomorphisms + between them. + + An *inverted* function field `M` is an extension of the base rational + function field `k(x)` of ``self``, and isomorphic to ``self`` by an + isomorphism sending `x` to `1/x`, which we call an *inversion* + isomorphism. Also the defining polynomial of the function field `M` is + required to be monic and integral. + + The inversion isomorphism is for internal use to reposition infinite + places to finite places. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: F._inversion_isomorphism() # optional - sage.libs.pari + (Function field in s defined by s^3 + x^16 + x^14 + x^12, Composite map: + From: Function field in s defined by s^3 + x^16 + x^14 + x^12 + To: Function field in y defined by y^3 + x^6 + x^4 + x^2 + Defn: Function Field morphism: + From: Function field in s defined by s^3 + x^16 + x^14 + x^12 + To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 + Defn: s |--> x^6*T + x |--> x + then + Function Field morphism: + From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 + To: Function field in y defined by y^3 + x^6 + x^4 + x^2 + Defn: T |--> y + x |--> 1/x, Composite map: + From: Function field in y defined by y^3 + x^6 + x^4 + x^2 + To: Function field in s defined by s^3 + x^16 + x^14 + x^12 + Defn: Function Field morphism: + From: Function field in y defined by y^3 + x^6 + x^4 + x^2 + To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 + Defn: y |--> T + x |--> 1/x + then + Function Field morphism: + From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6 + To: Function field in s defined by s^3 + x^16 + x^14 + x^12 + Defn: T |--> 1/x^6*s + x |--> x) + """ + K = self.base_field() + R = PolynomialRing(K,'T') + x = K.gen() + xinv = 1/x + + h = K.hom(xinv) + F_poly = R([h(c) for c in self.polynomial().list()]) + F = K.extension(F_poly) + + self2F = self.hom([F.gen(),xinv]) + F2self = F.hom([self.gen(),xinv]) + + M, M2F, F2M = F.monic_integral_model('s') + + return M, F2self*M2F, F2M*self2F + + def places_above(self, p): + """ + Return places lying above ``p``. + + INPUT: + + - ``p`` -- place of the base rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: all(q.place_below() == p # optional - sage.libs.pari + ....: for p in K.places() for q in F.places_above(p)) + True + + sage: K. = FunctionField(QQ); _. = K[] + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = K.maximal_order() # optional - sage.libs.singular + sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] # optional - sage.libs.singular + sage: all(q.place_below() == p # optional - sage.libs.singular + ....: for p in pls for q in F.places_above(p)) + True + + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field + sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular sage.rings.number_field + ....: for c in [-2, -1, 0, 1, 2]] + sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular sage.rings.number_field + ....: for p in pls for q in F.places_above(p)) + True + """ + R = self.base_field() + + if p not in R.place_set(): + raise TypeError("not a place of the base rational function field") + + if p.is_infinite_place(): + dec = self.maximal_order_infinite().decomposition() + else: + dec = self.maximal_order().decomposition(p.prime_ideal()) + + return tuple([q.place() for q, deg, exp in dec]) + + def constant_field(self): + """ + Return the algebraic closure of the base constant field in the function + field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari + sage: L.constant_field() # optional - sage.libs.pari + Finite Field of size 3 + """ + return self.exact_constant_field()[0] + + def exact_constant_field(self, name='t'): + """ + Return the exact constant field and its embedding into the function field. + + INPUT: + + - ``name`` -- name (default: `t`) of the generator of the exact constant field + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari + sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible # optional - sage.libs.pari + sage: L. = K.extension(f) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari + 0 + sage: L.exact_constant_field() # optional - sage.libs.pari + (Finite Field in t of size 3^2, Ring morphism: + From: Finite Field in t of size 3^2 + To: Function field in y defined by y^2 + 2*x*y + x^2 + 1 + Defn: t |--> y + x) + sage: (y+x).divisor() # optional - sage.libs.pari + 0 + """ + # A basis of the full constant field is obtained from + # computing a Riemann-Roch basis of zero divisor. + basis = self.divisor_group().zero().basis_function_space() + + dim = len(basis) + + for e in basis: + _min_poly = e.minimal_polynomial(name) + if _min_poly.degree() == dim: + break + k = self.constant_base_field() + R = k[name] + min_poly = R([k(c) for c in _min_poly.list()]) + + k_ext = k.extension(min_poly, name) + + if k_ext.is_prime_field(): + # The cover of the quotient ring k_ext is the integer ring + # whose generator is 1. This is different from the generator + # of k_ext. + embedding = k_ext.hom([self(1)], self) + else: + embedding = k_ext.hom([e], self) + + return k_ext, embedding + + def genus(self): + """ + Return the genus of the function field. + + EXAMPLES:: + + sage: F. = GF(16) # optional - sage.libs.pari + sage: K. = FunctionField(F); K # optional - sage.libs.pari + Rational function field in x over Finite Field in a of size 2^4 + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari + 6 + + The genus is computed by the Hurwitz genus formula. + """ + k, _ = self.exact_constant_field() + different_degree = self.different().degree() # must be even + return Integer(different_degree // 2 - self.degree() / k.degree()) + 1 + + def residue_field(self, place, name=None): + """ + Return the residue field associated with the place along with the maps + from and to the residue field. + + INPUT: + + - ``place`` -- place of the function field + + - ``name`` -- string; name of the generator of the residue field + + The domain of the map to the residue field is the discrete valuation + ring associated with the place. + + The discrete valuation ring is defined as the ring of all elements of + the function field with nonnegative valuation at the place. The maximal + ideal is the set of elements of positive valuation. The residue field + is then the quotient of the discrete valuation ring by its maximal + ideal. + + If an element not in the valuation ring is applied to the map, an + exception ``TypeError`` is raised. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: R, fr_R, to_R = L.residue_field(p) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Finite Field of size 2 + sage: f = 1 + y # optional - sage.libs.pari + sage: f.valuation(p) # optional - sage.libs.pari + -1 + sage: to_R(f) # optional - sage.libs.pari + Traceback (most recent call last): + ... + TypeError: ... + sage: (1+1/f).valuation(p) # optional - sage.libs.pari + 0 + sage: to_R(1 + 1/f) # optional - sage.libs.pari + 1 + sage: [fr_R(e) for e in R] # optional - sage.libs.pari + [0, 1] + """ + return place.residue_field(name=name) + + +class FunctionField_char_zero(FunctionField_simple): + """ + Function fields of characteristic zero. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular + sage: L # optional - sage.libs.singular + Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) + sage: L.characteristic() # optional - sage.libs.singular + 0 + """ + @cached_method + def higher_derivation(self): + """ + Return the higher derivation (also called the Hasse-Schmidt derivation) + for the function field. + + The higher derivation of the function field is uniquely determined with + respect to the separating element `x` of the base rational function + field `k(x)`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular + sage: L.higher_derivation() # optional - sage.libs.singular sage.modules + Higher derivation map: + From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) + To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) + """ + from .derivations_polymod import FunctionFieldHigherDerivation_char_zero + return FunctionFieldHigherDerivation_char_zero(self) + + +class FunctionField_global(FunctionField_simple): + """ + Global function fields. + + INPUT: + + - ``polynomial`` -- monic irreducible and separable polynomial + + - ``names`` -- name of the generator of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L # optional - sage.libs.pari + Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) + + The defining equation needs not be monic:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension((1 - x)*Y^7 - x^3) # optional - sage.libs.pari + sage: L.gaps() # long time (6s) # optional - sage.libs.pari + [1, 2, 3] + + or may define a trivial extension:: + + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y-1) # optional - sage.libs.pari + sage: L.genus() # optional - sage.libs.pari + 0 + """ + _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') + + def __init__(self, polynomial, names): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: TestSuite(L).run() # long time (7s) # optional - sage.libs.pari + """ + FunctionField_polymod.__init__(self, polynomial, names) + + def maximal_order(self): + """ + Return the maximal order of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari + (1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y) + """ + from .order_polymod import FunctionFieldMaximalOrder_global + return FunctionFieldMaximalOrder_global(self) + + @cached_method + def higher_derivation(self): + """ + Return the higher derivation (also called the Hasse-Schmidt derivation) + for the function field. + + The higher derivation of the function field is uniquely determined with + respect to the separating element `x` of the base rational function + field `k(x)`. + + EXAMPLES:: + + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari + sage: L.higher_derivation() # optional - sage.libs.pari sage.modules + Higher derivation map: + From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) + To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) + """ + from .derivations_polymod import FunctionFieldHigherDerivation_global + return FunctionFieldHigherDerivation_global(self) + + def get_place(self, degree): + """ + Return a place of ``degree``. + + INPUT: + + - ``degree`` -- a positive integer + + OUTPUT: a place of ``degree`` if any exists; otherwise ``None`` + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(Y^4 + Y - x^5) # optional - sage.libs.pari + sage: L.get_place(1) # optional - sage.libs.pari + Place (x, y) + sage: L.get_place(2) # optional - sage.libs.pari + Place (x, y^2 + y + 1) + sage: L.get_place(3) # optional - sage.libs.pari + Place (x^3 + x^2 + 1, y + x^2 + x) + sage: L.get_place(4) # optional - sage.libs.pari + Place (x + 1, x^5 + 1) + sage: L.get_place(5) # optional - sage.libs.pari + Place (x^5 + x^3 + x^2 + x + 1, y + x^4 + 1) + sage: L.get_place(6) # optional - sage.libs.pari + Place (x^3 + x^2 + 1, y^2 + y + x^2) + sage: L.get_place(7) # optional - sage.libs.pari + Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x) + sage: L.get_place(8) # optional - sage.libs.pari + + """ + for p in self._places_finite(degree): + return p + + for p in self._places_infinite(degree): + return p + + return None + + def places(self, degree=1): + """ + Return a list of the places with ``degree``. + + INPUT: + + - ``degree`` -- positive integer (default: `1`) + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places(1) # optional - sage.libs.pari + [Place (1/x, 1/x^4*y^3), Place (x, y), Place (x, y + 1)] + """ + return self.places_infinite(degree) + self.places_finite(degree) + + def places_finite(self, degree=1): + """ + Return a list of the finite places with ``degree``. + + INPUT: + + - ``degree`` -- positive integer (default: `1`) + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places_finite(1) # optional - sage.libs.pari + [Place (x, y), Place (x, y + 1)] + """ + return list(self._places_finite(degree)) + + def _places_finite(self, degree): + """ + Return a generator of finite places with ``degree``. + + INPUT: + + - ``degree`` -- positive integer + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L._places_finite(1) # optional - sage.libs.pari + + """ + O = self.maximal_order() + K = self.base_field() + + degree = Integer(degree) + + for d in degree.divisors(): + for p in K._places_finite(degree=d): + for prime,_,_ in O.decomposition(p.prime_ideal()): + place = prime.place() + if place.degree() == degree: + yield place + + def places_infinite(self, degree=1): + """ + Return a list of the infinite places with ``degree``. + + INPUT: + + - ``degree`` -- positive integer (default: `1`) + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L.places_infinite(1) # optional - sage.libs.pari + [Place (1/x, 1/x^4*y^3)] + """ + return list(self._places_infinite(degree)) + + def _places_infinite(self, degree): + """ + Return a generator of *infinite* places with ``degree``. + + INPUT: + + - ``degree`` -- positive integer + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari + sage: L._places_infinite(1) # optional - sage.libs.pari + + """ + Oinf = self.maximal_order_infinite() + for prime,_,_ in Oinf.decomposition(): + place = prime.place() + if place.degree() == degree: + yield place + + def gaps(self): + """ + Return the gaps of the function field. + + These are the gaps at the ordinary places, that is, places which are + not Weierstrass places. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: L.gaps() # optional - sage.libs.pari sage.modules + [1, 2, 3] + """ + return self._weierstrass_places()[1] + + def weierstrass_places(self): + """ + Return all Weierstrass places of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules + [Place (1/x, 1/x^3*y^2 + 1/x), + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), + Place (x, y), + Place (x + 1, (x^3 + 1)*y + x + 1), + Place (x^3 + x + 1, y + 1), + Place (x^3 + x + 1, y + x^2), + Place (x^3 + x + 1, y + x^2 + 1), + Place (x^3 + x^2 + 1, y + x), + Place (x^3 + x^2 + 1, y + x^2 + 1), + Place (x^3 + x^2 + 1, y + x^2 + x + 1)] + """ + return self._weierstrass_places()[0].support() + + @cached_method + def _weierstrass_places(self): + """ + Return the Weierstrass places together with the gap sequence for + ordinary places. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari sage.modules + 10 + + This method implements Algorithm 30 in [Hes2002b]_. + """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + W = self(self.base_field().gen()).differential().divisor() + basis = W._basis() + + if not basis: + return [], [] + d = len(basis) + + der = self.higher_derivation() + M = matrix([basis]) + e = 1 + gaps = [1] + while M.nrows() < d: + row = vector([der._derive(basis[i], e) for i in range(d)]) + if row not in M.row_space(): + M = matrix(M.rows() + [row]) + gaps.append(e + 1) + e += 1 + + # This is faster than M.determinant(). Note that Mx + # is a matrix over univariate polynomial ring. + Mx = matrix(M.nrows(), [c._x for c in M.list()]) + detM = self(Mx.determinant() % self._polynomial) + + R = detM.divisor() + sum(gaps)*W # ramification divisor + + return R, gaps + + @cached_method + def L_polynomial(self, name='t'): + """ + Return the L-polynomial of the function field. + + INPUT: + + - ``name`` -- (default: ``t``) name of the variable of the polynomial + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: F.L_polynomial() # optional - sage.libs.pari + 2*t^2 + t + 1 + """ + from sage.rings.integer_ring import ZZ + q = self.constant_field().order() + g = self.genus() + + B = [len(self.places(i+1)) for i in range(g)] + N = [sum(d * B[d-1] for d in ZZ(i+1).divisors()) for i in range(g)] + S = [N[i] - q**(i+1) - 1 for i in range(g)] + + a = [1] + for i in range(1, g+1): + a.append(sum(S[j] * a[i-j-1] for j in range(i)) / i) + for j in range(1, g+1): + a.append(q**j * a[g-j]) + + return ZZ[name](a) + + def number_of_rational_places(self, r=1): + """ + Return the number of rational places of the function field whose + constant field extended by degree ``r``. + + INPUT: + + - ``r`` -- positive integer (default: `1`) + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: F.number_of_rational_places() # optional - sage.libs.pari + 4 + sage: [F.number_of_rational_places(r) for r in [1..10]] # optional - sage.libs.pari + [4, 8, 4, 16, 44, 56, 116, 288, 508, 968] + """ + from sage.rings.integer_ring import IntegerRing + + q = self.constant_field().order() + L = self.L_polynomial() + Lp = L.derivative() + + R = IntegerRing()[[L.parent().gen()]] # power series ring + + f = R(Lp / L, prec=r) + n = f[r-1] + q**r + 1 + + return n + + +@handle_AA_and_QQbar +def _singular_normal(ideal): + r""" + Compute the normalization of the affine algebra defined by ``ideal`` using + Singular. + + The affine algebra is the quotient algebra of a multivariate polynomial + ring `R` by the ideal. The normalization is by definition the integral + closure of the algebra in its total ring of fractions. + + INPUT: + + - ``ideal`` -- a radical ideal in a multivariate polynomial ring + + OUTPUT: + + a list of lists, one list for each ideal in the equidimensional + decomposition of the ``ideal``, each list giving a set of generators of the + normalization of each ideal as an R-module by dividing all elements of the + list by the final element. Thus the list ``[x, y]`` means that `\{x/y, 1\}` + is the set of generators of the normalization of `R/(x,y)`. + + ALGORITHM: + + Singular's implementation of the normalization algorithm described in G.-M. + Greuel, S. Laplagne, F. Seelisch: Normalization of Rings (2009). + + EXAMPLES:: + + sage: from sage.rings.function_field.function_field_polymod import _singular_normal + sage: R. = QQ[] + + sage: f = (x^2 - y^3) * x + sage: _singular_normal(ideal(f)) # optional - sage.libs.singular + [[x, y], [1]] + + sage: f = y^2 - x + sage: _singular_normal(ideal(f)) # optional - sage.libs.singular + [[1]] + """ + from sage.libs.singular.function import singular_function, lib + lib('normal.lib') + normal = singular_function('normal') + execute = singular_function('execute') + + try: + get_printlevel = singular_function('get_printlevel') + except NameError: + execute('proc get_printlevel {return (printlevel);}') + get_printlevel = singular_function('get_printlevel') + + # It's fairly verbose unless printlevel is -1. + saved_printlevel = get_printlevel() + execute('printlevel=-1') + nor = normal(ideal) + execute('printlevel={}'.format(saved_printlevel)) + + return nor[1] + + +class FunctionField_integral(FunctionField_simple): + """ + Integral function fields. + + A function field is integral if it is defined by an irreducible separable + polynomial, which is integral over the maximal order of the base rational + function field. + """ + def _maximal_order_basis(self): + """ + Return a basis of the maximal order of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari + sage: F._maximal_order_basis() # optional - sage.libs.pari + [1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y] + + The basis of the maximal order *always* starts with 1. This is assumed + in some algorithms. + """ + from sage.matrix.constructor import matrix + from .hermite_form_polynomial import reversed_hermite_form + + k = self.constant_base_field() + K = self.base_field() # rational function field + n = self.degree() + + # Construct the defining polynomial of the function field as a + # two-variate polynomial g in the ring k[y,x] where k is the constant + # base field. + S,(y,x) = PolynomialRing(k, names='y,x', order='lex').objgens() + v = self.polynomial().list() + g = sum([v[i].numerator().subs(x) * y**i for i in range(len(v))]) + + if self.is_global(): + from sage.libs.singular.function import singular_function, lib + from sage.env import SAGE_EXTCODE + lib(SAGE_EXTCODE + '/singular/function_field/core.lib') + normalize = singular_function('core_normalize') + + # Singular "normalP" algorithm assumes affine domain over + # a prime field. So we construct gflat lifting g as in + # k_prime[yy,xx,zz]/(k_poly) where k = k_prime[zz]/(k_poly) + R = PolynomialRing(k.prime_subfield(), names='yy,xx,zz') + gflat = R.zero() + for m in g.monomials(): + c = g.monomial_coefficient(m).polynomial('zz') + gflat += R(c) * R(m) # R(m) is a monomial in yy and xx + + k_poly = R(k.polynomial('zz')) + + # invoke Singular + pols_in_R = normalize(R.ideal([k_poly, gflat])) + + # reconstruct polynomials in S + h = R.hom([y,x,k.gen()],S) + pols_in_S = [h(f) for f in pols_in_R] + else: + # Call Singular. Singular's "normal" function returns a basis + # of the integral closure of k(x,y)/(g) as a k[x,y]-module. + pols_in_S = _singular_normal(S.ideal(g))[0] + + # reconstruct the polynomials in the function field + x = K.gen() + y = self.gen() + pols = [] + for f in pols_in_S: + p = f.polynomial(S.gen(0)) + s = 0 + for i in range(p.degree()+1): + s += p[i].subs(x) * y**i + pols.append(s) + + # Now if pols = [g1,g2,...gn,g0], then the g1/g0,g2/g0,...,gn/g0, + # and g0/g0=1 are the module generators of the integral closure + # of the equation order Sb = k[xb,yb] in its fraction field, + # that is, the function field. The integral closure of k[x] + # is then obtained by multiplying these generators with powers of y + # as the equation order itself is an integral extension of k[x]. + d = ~ pols[-1] + _basis = [] + for f in pols: + b = d * f + for i in range(n): + _basis.append(b) + b *= y + + # Finally we reduce _basis to get a basis over k[x]. This is done of + # course by Hermite normal form computation. Here we apply a trick to + # get a basis that starts with 1 and is ordered in increasing + # y-degrees. The trick is to use the reversed Hermite normal form. + # Note that it is important that the overall denominator l lies in k[x]. + V, fr_V, to_V = self.free_module() + basis_V = [to_V(bvec) for bvec in _basis] + l = lcm([vvec.denominator() for vvec in basis_V]) + + _mat = matrix([[coeff.numerator() for coeff in l*v] for v in basis_V]) + reversed_hermite_form(_mat) + + basis = [fr_V(v) / l for v in _mat if not v.is_zero()] + return basis + + @cached_method + def equation_order(self): + """ + Return the equation order of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.equation_order() # optional - sage.libs.pari + Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 + + sage: K. = FunctionField(QQ); R. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: F.equation_order() # optional - sage.libs.singular + Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 + """ + from .order import FunctionFieldOrder_basis + a = self.gen() + basis = [a**i for i in range(self.degree())] + return FunctionFieldOrder_basis(tuple(basis)) + + @cached_method + def primitive_integal_element_infinite(self): + """ + Return a primitive integral element over the base maximal infinite order. + + This element is integral over the maximal infinite order of the base + rational function field and the function field is a simple extension by + this element over the base order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: b = F.primitive_integal_element_infinite(); b # optional - sage.libs.pari + 1/x^2*y + sage: b.minimal_polynomial('t') # optional - sage.libs.pari + t^3 + (x^4 + x^2 + 1)/x^4 + """ + f = self.polynomial() + n = f.degree() + y = self.gen() + x = self.base_field().gen() + + cf = max([(f[i].numerator().degree()/(n-i)).ceil() for i in range(n) + if f[i] != 0]) + return y*x**(-cf) + + @cached_method + def equation_order_infinite(self): + """ + Return the infinite equation order of the function field. + + This is by definition `o[b]` where `b` is the primitive integral + element from :meth:`primitive_integal_element_infinite()` and `o` is + the maximal infinite order of the base rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.equation_order_infinite() # optional - sage.libs.pari + Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 + + sage: K. = FunctionField(QQ); R. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: F.equation_order_infinite() # optional - sage.libs.singular + Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 + """ + from .order import FunctionFieldOrderInfinite_basis + b = self.primitive_integal_element_infinite() + basis = [b**i for i in range(self.degree())] + return FunctionFieldOrderInfinite_basis(tuple(basis)) + + +class FunctionField_char_zero_integral(FunctionField_char_zero, FunctionField_integral): + """ + Function fields of characteristic zero, defined by an irreducible and + separable polynomial, integral over the maximal order of the base rational + function field with a finite constant field. + """ + pass + + +class FunctionField_global_integral(FunctionField_global, FunctionField_integral): + """ + Global function fields, defined by an irreducible and separable polynomial, + integral over the maximal order of the base rational function field with a + finite constant field. + """ + pass + diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py new file mode 100644 index 00000000000..726d939fc54 --- /dev/null +++ b/src/sage/rings/function_field/function_field_rational.py @@ -0,0 +1,992 @@ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.arith.functions import lcm +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import LazyImport +from sage.structure.category_object import CategoryObject +from sage.rings.integer import Integer +from sage.categories.homset import Hom +from sage.categories.function_fields import FunctionFields + +from .element import FunctionFieldElement +from .element_rational import FunctionFieldElement_rational +from .function_field import FunctionField + + +class RationalFunctionField(FunctionField): + """ + Rational function field in one variable, over an arbitrary base field. + + INPUT: + + - ``constant_field`` -- arbitrary field + + - ``names`` -- string or tuple of length 1 + + EXAMPLES:: + + sage: K. = FunctionField(GF(3)); K # optional - sage.libs.pari + Rational function field in t over Finite Field of size 3 + sage: K.gen() # optional - sage.libs.pari + t + sage: 1/t + t^3 + 5 # optional - sage.libs.pari + (t^4 + 2*t + 1)/t + + sage: K. = FunctionField(QQ); K + Rational function field in t over Rational Field + sage: K.gen() + t + sage: 1/t + t^3 + 5 + (t^4 + 5*t + 1)/t + + There are various ways to get at the underlying fields and rings + associated to a rational function field:: + + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.base_field() # optional - sage.libs.pari + Rational function field in t over Finite Field of size 7 + sage: K.field() # optional - sage.libs.pari + Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 + sage: K.constant_field() # optional - sage.libs.pari + Finite Field of size 7 + sage: K.maximal_order() # optional - sage.libs.pari + Maximal order of Rational function field in t over Finite Field of size 7 + + sage: K. = FunctionField(QQ) + sage: K.base_field() + Rational function field in t over Rational Field + sage: K.field() + Fraction Field of Univariate Polynomial Ring in t over Rational Field + sage: K.constant_field() + Rational Field + sage: K.maximal_order() + Maximal order of Rational function field in t over Rational Field + + We define a morphism:: + + sage: K. = FunctionField(QQ) + sage: L = FunctionField(QQ, 'tbar') # give variable name as second input + sage: K.hom(L.gen()) + Function Field morphism: + From: Rational function field in t over Rational Field + To: Rational function field in tbar over Rational Field + Defn: t |--> tbar + + Here are some calculations over a number field:: + + sage: R. = FunctionField(QQ) + sage: L. = R[] + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular + sage: (y/x).divisor() # optional - sage.libs.singular sage.modules + - Place (x, y - 1) + - Place (x, y + 1) + + Place (x^2 + 1, y) + + sage: A. = QQ[] # optional - sage.rings.number_field + sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: R. = FunctionField(NF) # optional - sage.rings.number_field + sage: L. = R[] # optional - sage.rings.number_field + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular sage.modules sage.rings.number_field + + sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field + -2*Place (1/x, 1/x*y - 1) + - 2*Place (1/x, 1/x*y + 1) + + Place (x, y - 1) + + Place (x, y + 1) + + sage: (x/y).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field + - Place (x - i, y) + + Place (x, y - 1) + + Place (x, y + 1) + - Place (x + i, y) + + """ + Element = FunctionFieldElement_rational + + def __init__(self, constant_field, names, category=None): + """ + Initialize. + + EXAMPLES:: + + sage: K. = FunctionField(CC); K + Rational function field in t over Complex Field with 53 bits of precision + sage: TestSuite(K).run() # long time (5s) + + sage: FunctionField(QQ[I], 'alpha') # optional - sage.rings.number_field + Rational function field in alpha over + Number Field in I with defining polynomial x^2 + 1 with I = 1*I + + Must be over a field:: + + sage: FunctionField(ZZ, 't') + Traceback (most recent call last): + ... + TypeError: constant_field must be a field + """ + if names is None: + raise ValueError("variable name must be specified") + elif not isinstance(names, tuple): + names = (names, ) + if not constant_field.is_field(): + raise TypeError("constant_field must be a field") + + self._constant_field = constant_field + + FunctionField.__init__(self, self, names=names, category=FunctionFields().or_subcategory(category)) + + from .place_rational import FunctionFieldPlace_rational + self._place_class = FunctionFieldPlace_rational + + R = constant_field[names[0]] + self._hash = hash((constant_field, names)) + self._ring = R + self._field = R.fraction_field() + + hom = Hom(self._field, self) + from .maps import FractionFieldToFunctionField + self.register_coercion(hom.__make_element_class__(FractionFieldToFunctionField)(hom.domain(), hom.codomain())) + + from sage.categories.sets_with_partial_maps import SetsWithPartialMaps + from sage.categories.morphism import SetMorphism + R.register_conversion(SetMorphism(self.Hom(R, SetsWithPartialMaps()), self._to_polynomial)) + + self._gen = self(R.gen()) + + def __reduce__(self): + """ + Return the arguments which were used to create this instance. The + rationale for this is explained in the documentation of + :class:`UniqueRepresentation`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: clazz,args = K.__reduce__() + sage: clazz(*args) + Rational function field in x over Rational Field + """ + from .constructor import FunctionField + return FunctionField, (self._constant_field, self._names) + + def __hash__(self): + """ + Return hash of the function field. + + The hash is formed from the constant field and the variable names. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: hash(K) == hash((K.constant_base_field(), K.variable_names())) + True + + """ + return self._hash + + def _repr_(self): + """ + Return string representation of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K._repr_() + 'Rational function field in t over Rational Field' + """ + return "Rational function field in %s over %s"%( + self.variable_name(), self._constant_field) + + def _element_constructor_(self, x): + r""" + Coerce ``x`` into an element of the function field, possibly not canonically. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: a = K._element_constructor_(K.maximal_order().gen()); a + t + sage: a.parent() + Rational function field in t over Rational Field + + TESTS: + + Conversion of a string:: + + sage: K('t') + t + sage: K('1/t') + 1/t + + Conversion of a constant polynomial over the function field:: + + sage: K(K.polynomial_ring().one()) + 1 + + Some indirect test of conversion:: + + sage: S. = K[] + sage: I = S * [x^2 - y^2, y - t] # optional - sage.libs.singular + sage: I.groebner_basis() # optional - sage.libs.singular + [x^2 - t^2, y - t] + + """ + if isinstance(x, FunctionFieldElement): + return self.element_class(self, self._field(x._x)) + try: + x = self._field(x) + except TypeError as Err: + try: + if x.parent() is self.polynomial_ring(): + return x[0] + except AttributeError: + pass + raise Err + return self.element_class(self, x) + + def _to_constant_base_field(self, f): + r""" + Return ``f`` as an element of the constant base field. + + INPUT: + + - ``f`` -- element of the rational function field which is a + constant of the underlying rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K._to_constant_base_field(K(1)) + 1 + sage: K._to_constant_base_field(K(x)) + Traceback (most recent call last): + ... + ValueError: only constants can be converted into the constant base field but x is not a constant + + TESTS: + + Verify that :trac:`21872` has been resolved:: + + sage: K(1) in QQ + True + sage: x in QQ + False + + """ + K = self.constant_base_field() + if f.denominator() in K and f.numerator() in K: + # When K is not exact, f.denominator() might not be an exact 1, so + # we need to divide explicitly to get the correct precision + return K(f.numerator()) / K(f.denominator()) + raise ValueError("only constants can be converted into the constant base field but %r is not a constant"%(f,)) + + def _to_polynomial(self, f): + """ + If ``f`` is integral, return it as a polynomial. + + INPUT: + + - ``f`` -- an element of this rational function field whose denominator is a constant. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K._ring(x) # indirect doctest + x + """ + K = f.parent().constant_base_field() + if f.denominator() in K: + return f.numerator()/K(f.denominator()) + raise ValueError("only polynomials can be converted to the underlying polynomial ring") + + def _to_bivariate_polynomial(self, f): + """ + Convert ``f`` from a univariate polynomial over the rational function + field into a bivariate polynomial and a denominator. + + INPUT: + + - ``f`` -- univariate polynomial over the function field + + OUTPUT: + + - bivariate polynomial, denominator + + EXAMPLES:: + + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari + sage: R._to_bivariate_polynomial(f) # optional - sage.libs.pari + (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) + """ + v = f.list() + denom = lcm([a.denominator() for a in v]) + S = denom.parent() + x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens() + phi = S.hom([t]) + return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom + + def _factor_univariate_polynomial(self, f, proof=None): + """ + Factor the univariate polynomial f over the function field. + + INPUT: + + - ``f`` -- univariate polynomial over the function field + + EXAMPLES: + + We do a factorization over the function field over the rationals:: + + sage: R. = FunctionField(QQ) + sage: S. = R[] + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) + sage: f.factor() # indirect doctest # optional - sage.libs.singular + (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2) + sage: f.factor().prod() == f # optional - sage.libs.singular + True + + We do a factorization over a finite prime field:: + + sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari + sage: f.factor() # optional - sage.libs.pari + (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t) + sage: f.factor().prod() == f # optional - sage.libs.pari + True + + Factoring over a function field over a non-prime finite field:: + + sage: k. = GF(9) # optional - sage.libs.pari + sage: R. = FunctionField(k) # optional - sage.libs.pari + sage: S. = R[] # optional - sage.libs.pari + sage: f = (1/t)*(X^3 - a*t^3) # optional - sage.libs.pari + sage: f.factor() # optional - sage.libs.pari + (1/t) * (X + (a + 2)*t)^3 + sage: f.factor().prod() == f # optional - sage.libs.pari + True + + Factoring over a function field over a tower of finite fields:: + + sage: k. = GF(4) # optional - sage.libs.pari + sage: R. = k[] # optional - sage.libs.pari + sage: l. = k.extension(b^2 + b + a) # optional - sage.libs.pari + sage: K. = FunctionField(l) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: F = t*x # optional - sage.libs.pari + sage: F.factor(proof=False) # optional - sage.libs.pari + (x) * t + + """ + old_variable_name = f.variable_name() + # the variables of the bivariate polynomial must be distinct + if self.variable_name() == f.variable_name(): + # replace x with xx to make the variable names distinct + f = f.change_variable_name(old_variable_name + old_variable_name) + + F, d = self._to_bivariate_polynomial(f) + fac = F.factor(proof=proof) + x = f.parent().gen() + t = f.parent().base_ring().gen() + phi = F.parent().hom([x, t]) + v = [(phi(P),e) for P, e in fac] + unit = phi(fac.unit())/d + w = [] + for a, e in v: + c = a.leading_coefficient() + a = a/c + # undo any variable substitution that we introduced for the bivariate polynomial + if old_variable_name != a.variable_name(): + a = a.change_variable_name(old_variable_name) + unit *= (c**e) + if a.is_unit(): + unit *= a**e + else: + w.append((a,e)) + from sage.structure.factorization import Factorization + return Factorization(w, unit=unit) + + def extension(self, f, names=None): + """ + Create an extension `L = K[y]/(f(y))` of the rational function field. + + INPUT: + + - ``f`` -- univariate polynomial over self + + - ``names`` -- string or length-1 tuple + + OUTPUT: + + - a function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular + Function field in y defined by y^5 + x*y - x^3 - 3*x + + A nonintegral defining polynomial:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular + Function field in y defined by y^3 + 1/t*y + t^3/(t + 1) + + The defining polynomial need not be monic or integral:: + + sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular + Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) + """ + from . import constructor + return constructor.FunctionFieldExtension(f, names) + + @cached_method + def polynomial_ring(self, var='x'): + """ + Return a polynomial ring in one variable over the rational function field. + + INPUT: + + - ``var`` -- string; name of the variable + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.polynomial_ring() + Univariate Polynomial Ring in x over Rational function field in x over Rational Field + sage: K.polynomial_ring('T') + Univariate Polynomial Ring in T over Rational function field in x over Rational Field + """ + return self[var] + + @cached_method(key=lambda self, base, basis, map: map) + def free_module(self, base=None, basis=None, map=True): + """ + Return a vector space `V` and isomorphisms from the field to `V` and + from `V` to the field. + + This function allows us to identify the elements of this field with + elements of a one-dimensional vector space over the field itself. This + method exists so that all function fields (rational or not) have the + same interface. + + INPUT: + + - ``base`` -- the base field of the vector space; must be the function + field itself (the default) + + - ``basis`` -- (ignored) a basis for the vector space + + - ``map`` -- (default ``True``), whether to return maps to and from the vector space + + OUTPUT: + + - a vector space `V` over base field + + - an isomorphism from `V` to the field + + - the inverse isomorphism from the field to `V` + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.free_module() # optional - sage.modules + (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: + From: Vector space of dimension 1 over Rational function field in x over Rational Field + To: Rational function field in x over Rational Field, Isomorphism: + From: Rational function field in x over Rational Field + To: Vector space of dimension 1 over Rational function field in x over Rational Field) + + TESTS:: + + sage: K.free_module() # optional - sage.modules + (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism: + From: Vector space of dimension 1 over Rational function field in x over Rational Field + To: Rational function field in x over Rational Field, Isomorphism: + From: Rational function field in x over Rational Field + To: Vector space of dimension 1 over Rational function field in x over Rational Field) + + """ + if basis is not None: + raise NotImplementedError + from .maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace + if base is None: + base = self + elif base is not self: + raise ValueError("base must be the rational function field itself") + V = base**1 + if not map: + return V + from_V = MapVectorSpaceToFunctionField(V, self) + to_V = MapFunctionFieldToVectorSpace(self, V) + return (V, from_V, to_V) + + def random_element(self, *args, **kwds): + """ + Create a random element of the rational function field. + + Parameters are passed to the random_element method of the + underlying fraction field. + + EXAMPLES:: + + sage: FunctionField(QQ,'alpha').random_element() # random + (-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95) + """ + return self(self._field.random_element(*args, **kwds)) + + def degree(self, base=None): + """ + Return the degree over the base field of the rational function + field. Since the base field is the rational function field itself, the + degree is 1. + + INPUT: + + - ``base`` -- the base field of the vector space; must be the function + field itself (the default) + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.degree() + 1 + """ + if base is None: + base = self + elif base is not self: + raise ValueError("base must be the rational function field itself") + from sage.rings.integer_ring import ZZ + return ZZ(1) + + def gen(self, n=0): + """ + Return the ``n``-th generator of the function field. If ``n`` is not + 0, then an IndexError is raised. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); K.gen() + t + sage: K.gen().parent() + Rational function field in t over Rational Field + sage: K.gen(1) + Traceback (most recent call last): + ... + IndexError: Only one generator. + """ + if n != 0: + raise IndexError("Only one generator.") + return self._gen + + def ngens(self): + """ + Return the number of generators, which is 1. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.ngens() + 1 + """ + return 1 + + def base_field(self): + """ + Return the base field of the rational function field, which is just + the function field itself. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.base_field() # optional - sage.libs.pari + Rational function field in t over Finite Field of size 7 + """ + return self + + def hom(self, im_gens, base_morphism=None): + """ + Create a homomorphism from ``self`` to another ring. + + INPUT: + + - ``im_gens`` -- exactly one element of some ring. It must be + invertible and transcendental over the image of + ``base_morphism``; this is not checked. + + - ``base_morphism`` -- a homomorphism from the base field into the + other ring. If ``None``, try to use a coercion map. + + OUTPUT: + + - a map between function fields + + EXAMPLES: + + We make a map from a rational function field to itself:: + + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.hom( (x^4 + 2)/x) # optional - sage.libs.pari + Function Field endomorphism of Rational function field in x over Finite Field of size 7 + Defn: x |--> (x^4 + 2)/x + + We construct a map from a rational function field into a + non-rational extension field:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari + sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari + Function Field morphism: + From: Rational function field in x over Finite Field of size 7 + To: Function field in y defined by y^3 + 6*x^3 + x + Defn: x |--> y^2 + y + 2 + sage: f(x) # optional - sage.libs.pari + y^2 + y + 2 + sage: f(x^2) # optional - sage.libs.pari + 5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4 + """ + if isinstance(im_gens, CategoryObject): + return self.Hom(im_gens).natural_map() + if not isinstance(im_gens, (list,tuple)): + im_gens = [im_gens] + if len(im_gens) != 1: + raise ValueError("there must be exactly one generator") + x = im_gens[0] + R = x.parent() + if base_morphism is None and not R.has_coerce_map_from(self.constant_field()): + raise ValueError("you must specify a morphism on the base field") + from .maps import FunctionFieldMorphism_rational + return FunctionFieldMorphism_rational(self.Hom(R), x, base_morphism) + + def field(self): + """ + Return the underlying field, forgetting the function field + structure. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari + sage: K.field() # optional - sage.libs.pari + Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 + + .. SEEALSO:: + + :meth:`sage.rings.fraction_field.FractionField_1poly_field.function_field` + + """ + return self._field + + @cached_method + def maximal_order(self): + """ + Return the maximal order of the function field. + + Since this is a rational function field it is of the form `K(t)`, and the + maximal order is by definition `K[t]`, where `K` is the constant field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.maximal_order() + Maximal order of Rational function field in t over Rational Field + sage: K.equation_order() + Maximal order of Rational function field in t over Rational Field + """ + from .order import FunctionFieldMaximalOrder_rational + return FunctionFieldMaximalOrder_rational(self) + + equation_order = maximal_order + + @cached_method + def maximal_order_infinite(self): + """ + Return the maximal infinite order of the function field. + + By definition, this is the valuation ring of the degree valuation of + the rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.maximal_order_infinite() + Maximal infinite order of Rational function field in t over Rational Field + sage: K.equation_order_infinite() + Maximal infinite order of Rational function field in t over Rational Field + """ + from .order import FunctionFieldMaximalOrderInfinite_rational + return FunctionFieldMaximalOrderInfinite_rational(self) + + equation_order_infinite = maximal_order_infinite + + def constant_base_field(self): + """ + Return the field of which the rational function field is a + transcendental extension. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.constant_base_field() + Rational Field + """ + return self._constant_field + + constant_field = constant_base_field + + def different(self): + """ + Return the different of the rational function field. + + For a rational function field, the different is simply the zero + divisor. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.different() # optional - sage.modules + 0 + """ + return self.divisor_group().zero() + + def genus(self): + """ + Return the genus of the function field, namely 0. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.genus() + 0 + """ + return Integer(0) + + def change_variable_name(self, name): + r""" + Return a field isomorphic to this field with variable ``name``. + + INPUT: + + - ``name`` -- a string or a tuple consisting of a single string, the + name of the new variable + + OUTPUT: + + A triple ``F,f,t`` where ``F`` is a rational function field, ``f`` is + an isomorphism from ``F`` to this field, and ``t`` is the inverse of + ``f``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: L,f,t = K.change_variable_name('y') + sage: L,f,t + (Rational function field in y over Rational Field, + Function Field morphism: + From: Rational function field in y over Rational Field + To: Rational function field in x over Rational Field + Defn: y |--> x, + Function Field morphism: + From: Rational function field in x over Rational Field + To: Rational function field in y over Rational Field + Defn: x |--> y) + sage: L.change_variable_name('x')[0] is K + True + + """ + if isinstance(name, tuple): + if len(name) != 1: + raise ValueError("names must be a tuple with a single string") + name = name[0] + if name == self.variable_name(): + id = Hom(self,self).identity() + return self,id,id + else: + from .constructor import FunctionField + ret = FunctionField(self.constant_base_field(), name) + return ret, ret.hom(self.gen()), self.hom(ret.gen()) + + def residue_field(self, place, name=None): + """ + Return the residue field of the place along with the maps from + and to it. + + INPUT: + + - ``place`` -- place of the function field + + - ``name`` -- string; name of the generator of the residue field + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: p = F.places_finite(2)[0] # optional - sage.libs.pari + sage: R, fr_R, to_R = F.residue_field(p) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Finite Field in z2 of size 5^2 + sage: to_R(x) in R # optional - sage.libs.pari + True + """ + return place.residue_field(name=name) + + +class RationalFunctionField_char_zero(RationalFunctionField): + """ + Rational function fields of characteristic zero. + """ + @cached_method + def higher_derivation(self): + """ + Return the higher derivation for the function field. + + This is also called the Hasse-Schmidt derivation. + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: d = F.higher_derivation() # optional - sage.modules + sage: [d(x^5,i) for i in range(10)] # optional - sage.modules + [x^5, 5*x^4, 10*x^3, 10*x^2, 5*x, 1, 0, 0, 0, 0] + sage: [d(x^9,i) for i in range(10)] # optional - sage.modules + [x^9, 9*x^8, 36*x^7, 84*x^6, 126*x^5, 126*x^4, 84*x^3, 36*x^2, 9*x, 1] + """ + from .derivations import FunctionFieldHigherDerivation_char_zero + return FunctionFieldHigherDerivation_char_zero(self) + + +class RationalFunctionField_global(RationalFunctionField): + """ + Rational function field over finite fields. + """ + _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') + + def places(self, degree=1): + """ + Return all places of the degree. + + INPUT: + + - ``degree`` -- (default: 1) a positive integer + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari + [Place (1/x), + Place (x), + Place (x + 1), + Place (x + 2), + Place (x + 3), + Place (x + 4)] + """ + if degree == 1: + return [self.place_infinite()] + self.places_finite(degree) + else: + return self.places_finite(degree) + + def places_finite(self, degree=1): + """ + Return the finite places of the degree. + + INPUT: + + - ``degree`` -- (default: 1) a positive integer + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.places_finite() # optional - sage.libs.pari + [Place (x), Place (x + 1), Place (x + 2), Place (x + 3), Place (x + 4)] + """ + return list(self._places_finite(degree)) + + def _places_finite(self, degree=1): + """ + Return a generator for all monic irreducible polynomials of the degree. + + INPUT: + + - ``degree`` -- (default: 1) a positive integer + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F._places_finite() # optional - sage.libs.pari + + """ + O = self.maximal_order() + R = O._ring + G = R.polynomials(max_degree=degree - 1) + lm = R.monomial(degree) + for g in G: + h = lm + g + if h.is_irreducible(): + yield O.ideal(h).place() + + def place_infinite(self): + """ + Return the unique place at infinity. + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: F.place_infinite() # optional - sage.libs.pari + Place (1/x) + """ + return self.maximal_order_infinite().prime_ideal().place() + + def get_place(self, degree): + """ + Return a place of ``degree``. + + INPUT: + + - ``degree`` -- a positive integer + + EXAMPLES:: + + sage: F. = GF(2) # optional - sage.libs.pari + sage: K. = FunctionField(F) # optional - sage.libs.pari + sage: K.get_place(1) # optional - sage.libs.pari + Place (x) + sage: K.get_place(2) # optional - sage.libs.pari + Place (x^2 + x + 1) + sage: K.get_place(3) # optional - sage.libs.pari + Place (x^3 + x + 1) + sage: K.get_place(4) # optional - sage.libs.pari + Place (x^4 + x + 1) + sage: K.get_place(5) # optional - sage.libs.pari + Place (x^5 + x^2 + 1) + + """ + for p in self._places_finite(degree): + return p + + assert False, "there is a bug around" + + @cached_method + def higher_derivation(self): + """ + Return the higher derivation for the function field. + + This is also called the Hasse-Schmidt derivation. + + EXAMPLES:: + + sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: d = F.higher_derivation() # optional - sage.libs.pari + sage: [d(x^5,i) for i in range(10)] # optional - sage.libs.pari + [x^5, 0, 0, 0, 0, 1, 0, 0, 0, 0] + sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari + [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] + """ + from .derivations import RationalFunctionFieldHigherDerivation_global + return RationalFunctionFieldHigherDerivation_global(self) diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py new file mode 100644 index 00000000000..c89722ebf20 --- /dev/null +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -0,0 +1,1693 @@ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +import itertools +from sage.rings.infinity import infinity +from sage.arith.power import generic_power +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute +from sage.structure.richcmp import richcmp +from sage.matrix.constructor import matrix + +from .ideal import FunctionFieldIdeal, FunctionFieldIdealInfinite + +class FunctionFieldIdeal_polymod(FunctionFieldIdeal): + """ + Fractional ideals of algebraic function fields + + INPUT: + + - ``ring`` -- order in a function field + + - ``hnf`` -- matrix in hermite normal form + + - ``denominator`` -- denominator + + The rows of ``hnf`` is a basis of the ideal, which itself is + ``denominator`` times the fractional ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.ideal(y) # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x + """ + def __init__(self, ring, hnf, denominator=1): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari + """ + FunctionFieldIdeal.__init__(self, ring) + + # the denominator and the entries of the hnf are + # univariate polynomials. + self._hnf = hnf + self._denominator = denominator + + # for prime ideals + self._relative_degree = None + self._ramification_index = None + self._prime_below = None + self._beta = None + + # beta in matrix form for fast multiplication + self._beta_matrix = None + + # (p, q) with irreducible polynomial p and q an element of O in vector + # form, together generating the prime ideal. This data is obtained by + # Kummer's theorem when this prime ideal is constructed. This is used + # for fast multiplication with other ideal. + self._kummer_form = None + + # tuple of at most two gens: + # the first gen is an element of the base ring of the maximal order + # the second gen is the vector form of an element of the maximal order + # if the second gen is zero, the tuple has only the first gen. + self._gens_two_vecs = None + + def __bool__(self): + """ + Test if this ideal is zero. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x + sage: I.is_zero() # optional - sage.libs.pari + False + sage: J = 0*I; J # optional - sage.libs.pari + Zero ideal of Maximal order of Function field in y defined by y^2 + x^3*y + x + sage: J.is_zero() # optional - sage.libs.pari + True + + sage: K.=FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari + sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y); I # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + sage: I.is_zero() # optional - sage.libs.pari + False + sage: J = 0*I; J # optional - sage.libs.pari + Zero ideal of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: J.is_zero() # optional - sage.libs.pari + True + """ + return self._hnf.nrows() != 0 + + + + def __hash__(self): + """ + Return the hash of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: { I: 2 }[I] == 2 # optional - sage.libs.pari + True + + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: { I: 2 }[I] == 2 # optional - sage.libs.pari + True + """ + return hash((self._ring, self._hnf, self._denominator)) + + def __contains__(self, x): + """ + Return ``True`` if ``x`` is in this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal([y]); I # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y + defined by y^2 + 6*x^3 + 6 + sage: x * y in I # optional - sage.libs.pari + True + sage: y / x in I # optional - sage.libs.pari + False + sage: y^2 - 2 in I # optional - sage.libs.pari + False + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal([y]); I # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + sage: x * y in I # optional - sage.libs.pari + True + sage: y / x in I # optional - sage.libs.pari + False + sage: y^2 - 2 in I # optional - sage.libs.pari + False + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal([y]); I # optional - sage.libs.singular + Ideal (y) of Maximal order of Function field in y + defined by y^2 - x^3 - 1 + sage: x * y in I # optional - sage.libs.singular + True + sage: y / x in I # optional - sage.libs.singular + False + sage: y^2 - 2 in I # optional - sage.libs.singular + False + + sage: K. = FunctionField(QQ); _. = K[] # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal([y]); I # optional - sage.libs.singular + Ideal (y) of Maximal order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + sage: x * y in I # optional - sage.libs.singular + True + sage: y / x in I # optional - sage.libs.singular + False + sage: y^2 - 2 in I # optional - sage.libs.singular + False + """ + from sage.modules.free_module_element import vector + + vec = self.ring().coordinate_vector(self._denominator * x) + v = [] + for e in vec: + if e.denominator() != 1: + return False + v.append(e.numerator()) + vec = vector(v) + return vec in self._hnf.image() + + def __invert__(self): + """ + Return the inverse fractional ideal of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari + Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + sage: I^(-1) # optional - sage.libs.pari + Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + sage: ~I * I # optional - sage.libs.pari + Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 + + :: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari + Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: I^(-1) # optional - sage.libs.pari + Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: ~I * I # optional - sage.libs.pari + Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x + + :: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: ~I # optional - sage.libs.singular + Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 + sage: I^(-1) # optional - sage.libs.singular + Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 + sage: ~I * I # optional - sage.libs.singular + Ideal (1) of Maximal order of Function field in y defined by y^2 - x^3 - 1 + + :: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: ~I # optional - sage.libs.singular + Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: I^(-1) # optional - sage.libs.singular + Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: ~I * I # optional - sage.libs.singular + Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + R = self.ring() + T = R._codifferent_matrix() + I = self * R.codifferent() + J = I._denominator * (I._hnf * T).inverse() + return R._ideal_from_vectors(J.columns()) + + def _richcmp_(self, other, op): + """ + Compare this ideal with the other ideal with respect to ``op``. + + INPUT: + + - ``other`` -- ideal + + - ``op`` -- comparison operator + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I == I + I # optional - sage.libs.pari + True + sage: I == I * I # optional - sage.libs.pari + False + + :: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I == I + I # optional - sage.libs.pari + True + sage: I == I * I # optional - sage.libs.pari + False + sage: I < I * I # optional - sage.libs.pari + True + sage: I > I * I # optional - sage.libs.pari + False + """ + return richcmp((self._denominator, self._hnf), (other._denominator, other._hnf), op) + + def _add_(self, other): + """ + Add with other ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x + + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari + Ideal (1, y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + ds = self._denominator + do = other._denominator + vecs1 = [do * r for r in self._hnf] + vecs2 = [ds * r for r in other._hnf] + return self._ring._ideal_from_vectors_and_denominator(vecs1 + vecs2, ds * do) + + def _mul_(self, other): + """ + Multiply with other ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari + Ideal (x^4 + x^2 + x, x*y + x^2) of Maximal order + of Function field in y defined by y^2 + x^3*y + x + + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari + Ideal ((x + 1)*y + (x^2 + 1)/x) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + O = self._ring + mul = O._mul_vecs + + if self._kummer_form is not None: + p, q = self._kummer_form + vecs = list(p * other._hnf) + [mul(q, v) for v in other._hnf] + elif other._kummer_form is not None: + p, q = other._kummer_form + vecs = list(p * self._hnf) + [mul(q, v) for v in self._hnf] + elif self._gens_two_vecs is not None: + if len(self._gens_two_vecs) == 1: + g1, = self._gens_two_vecs + vecs = list(g1 * other._hnf) + else: + g1, g2 = self._gens_two_vecs + vecs = list(g1 * other._hnf) + [mul(g2, v) for v in other._hnf] + elif other._gens_two_vecs is not None: + if len(other._gens_two_vecs) == 1: + g1, = other._gens_two_vecs + vecs = list(g1 * self._hnf) + else: + g1, g2 = other._gens_two_vecs + vecs = list(g1 * self._hnf) + [mul(g2, v) for v in self._hnf] + else: + vecs = [mul(r1,r2) for r1 in self._hnf for r2 in other._hnf] + + return O._ideal_from_vectors_and_denominator(vecs, self._denominator * other._denominator) + + def _acted_upon_(self, other, on_left): + """ + Multiply ``other`` and this ideal on the right. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: x * I == I * J # optional - sage.libs.pari + True + + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: x * I == I * J # optional - sage.libs.pari + True + """ + from sage.modules.free_module_element import vector + + O = self._ring + mul = O._mul_vecs + + # compute the vector form of other element + v = O.coordinate_vector(other) + d = v.denominator() + vec = vector([(d * c).numerator() for c in v]) + + # multiply with the ideal + vecs = [mul(vec, r) for r in self._hnf] + + return O._ideal_from_vectors_and_denominator(vecs, d * self._denominator) + + def intersect(self, other): + """ + Intersect this ideal with the other ideal as fractional ideals. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x) # optional - sage.libs.pari + sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.libs.pari + True + + """ + from sage.matrix.special import block_matrix + from .hermite_form_polynomial import reversed_hermite_form + + A = self._hnf + B = other._hnf + + ds = self.denominator() + do = other.denominator() + d = ds.lcm(do) + if not d.is_one(): + A = (d // ds) * A + B = (d // do) * B + + MS = A.matrix_space() + I = MS.identity_matrix() + O = MS.zero() + n = A.ncols() + + # intersect the row spaces of A and B + M = block_matrix([[I,I],[A,O],[O,B]]) + + # reversed Hermite form + U = reversed_hermite_form(M, transformation=True) + + vecs = [U[i][:n] for i in range(n)] + + return self._ring._ideal_from_vectors_and_denominator(vecs, d) + + def hnf(self): + """ + Return the matrix in hermite normal form representing this ideal. + + See also :meth:`denominator` + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.pari + [x^6 + x^3 0] + [ x^3 + 1 1] + + :: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.singular + [x^6 + x^3 0] + [ x^3 + 1 1] + """ + return self._hnf + + def denominator(self): + """ + Return the denominator of this fractional ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y/(y+1)) # optional - sage.libs.pari + sage: d = I.denominator(); d # optional - sage.libs.pari + x^3 + sage: d in O # optional - sage.libs.pari + True + + :: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: O = L.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y/(y+1)) # optional - sage.libs.singular + sage: d = I.denominator(); d # optional - sage.libs.singular + x^3 + sage: d in O # optional - sage.libs.singular + True + """ + return self._denominator + + @cached_method + def module(self): + """ + Return the module, that is the ideal viewed as a module + over the base maximal order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.module() # optional - sage.libs.pari + Free module of degree 2 and rank 2 over Maximal order + of Rational function field in x over Finite Field of size 7 + Echelon basis matrix: + [ 1 0] + [ 0 1/(x^3 + 1)] + """ + F = self.ring().fraction_field() + V, fr, to = F.vector_space() + O = F.base_field().maximal_order() + return V.span([to(g) for g in self.gens_over_base()], base_ring=O) + + @cached_method + def gens_over_base(self): + """ + Return the generators of this ideal as a module over the maximal order + of the base rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari + (x^4 + x^2 + x, y + x) + + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari + (x^3 + 1, y + x) + """ + gens, d = self._gens_over_base + return tuple([~d * b for b in gens]) + + @lazy_attribute + def _gens_over_base(self): + """ + Return the generators of the integral ideal, which is the denominator + times the fractional ideal, together with the denominator. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(1/y) # optional - sage.libs.pari + sage: I._gens_over_base # optional - sage.libs.pari + ([x, y], x) + """ + gens = [] + for row in self._hnf: + gens.append(sum([c1*c2 for c1,c2 in zip(row, self._ring.basis())])) + return gens, self._denominator + + def gens(self): + """ + Return a set of generators of this ideal. + + This provides whatever set of generators as quickly + as possible. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^4 + x^2 + x, y + x) + + sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^3 + 1, y + x) + """ + return self.gens_over_base() + + @cached_method + def basis_matrix(self): + """ + Return the matrix of basis vectors of this ideal as a module. + + The basis matrix is by definition the hermite norm form of the ideal + divided by the denominator. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.libs.pari + True + """ + d = self.denominator() + m = (d * self).hnf() + if d != 1: + m = ~d * m + m.set_immutable() + return m + + def is_integral(self): + """ + Return ``True`` if this is an integral ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.is_integral() # optional - sage.libs.pari + False + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.is_integral() # optional - sage.libs.pari + True + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.is_integral() # optional - sage.libs.pari + False + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.is_integral() # optional - sage.libs.pari + True + + sage: K. = FunctionField(QQ); _. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular + sage: I.is_integral() # optional - sage.libs.singular + False + sage: J = I.denominator() * I # optional - sage.libs.singular + sage: J.is_integral() # optional - sage.libs.singular + True + """ + return self.denominator() == 1 + + def ideal_below(self): + """ + Return the ideal below this ideal. + + This is defined only for integral ideals. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari + Traceback (most recent call last): + ... + TypeError: not an integral ideal + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.ideal_below() # optional - sage.libs.pari + Ideal (x^3 + x^2 + x) of Maximal order of Rational function field + in x over Finite Field of size 2 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari + Traceback (most recent call last): + ... + TypeError: not an integral ideal + sage: J = I.denominator() * I # optional - sage.libs.pari + sage: J.ideal_below() # optional - sage.libs.pari + Ideal (x^3 + x) of Maximal order of Rational function field + in x over Finite Field of size 2 + + sage: K. = FunctionField(QQ); _. = K[] + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular + sage: I.ideal_below() # optional - sage.libs.singular + Traceback (most recent call last): + ... + TypeError: not an integral ideal + sage: J = I.denominator() * I # optional - sage.libs.singular + sage: J.ideal_below() # optional - sage.libs.singular + Ideal (x^3 + x^2 + x) of Maximal order of Rational function field + in x over Rational Field + """ + if not self.is_integral(): + raise TypeError("not an integral ideal") + + K = self.ring().fraction_field().base_field().maximal_order() + + # self._hnf is in reversed hermite normal form, that is, lower + # triangular form. Thus the generator of the ideal below is + # just the (0,0) entry of the normal form. When self._hnf was in + # hermite normal form, that is, upper triangular form, then the + # generator can be computed in the following way: + # + # m = matrix([hnf[0].parent().gen(0)] + list(hnf)) + # _,T = m.hermite_form(transformation=True) + # return T[-1][0] + # + # This is certainly less efficient! This is an argument for using + # reversed hermite normal form for ideal representation. + l = self._hnf[0][0] + + return K.ideal(l) + + def norm(self): + """ + Return the norm of this fractional ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i1 = O.ideal(x) # optional - sage.libs.pari + sage: i2 = O.ideal(y) # optional - sage.libs.pari + sage: i3 = i1 * i2 # optional - sage.libs.pari + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari + True + sage: i1.norm() # optional - sage.libs.pari + x^3 + sage: i1.norm() == x ** F.degree() # optional - sage.libs.pari + True + sage: i2.norm() # optional - sage.libs.pari + x^6 + x^4 + x^2 + sage: i2.norm() == y.norm() # optional - sage.libs.pari + True + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: i1 = O.ideal(x) # optional - sage.libs.pari + sage: i2 = O.ideal(y) # optional - sage.libs.pari + sage: i3 = i1 * i2 # optional - sage.libs.pari + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari + True + sage: i1.norm() # optional - sage.libs.pari + x^2 + sage: i1.norm() == x ** L.degree() # optional - sage.libs.pari + True + sage: i2.norm() # optional - sage.libs.pari + (x^2 + 1)/x + sage: i2.norm() == y.norm() # optional - sage.libs.pari + True + """ + n = 1 + for e in self.basis_matrix().diagonal(): + n *= e + return n + + @cached_method + def is_prime(self): + """ + Return ``True`` if this ideal is a prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari + [True, True] + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari + [True, True] + + sage: K. = FunctionField(QQ); _. = PolynomialRing(K) + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.singular + [True, True] + """ + factors = self.factor() + if len(factors) == 1 and factors[0][1] == 1: # prime! + prime = factors[0][0] + assert self == prime + self._relative_degree = prime._relative_degree + self._ramification_index = prime._ramification_index + self._prime_below = prime._prime_below + self._beta = prime._beta + self._beta_matrix = prime._beta_matrix + return True + else: + return False + + ################################################### + # The following methods are only for prime ideals # + ################################################### + + def valuation(self, ideal): + """ + Return the valuation of ``ideal`` at this prime ideal. + + INPUT: + + - ``ideal`` -- fractional ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.libs.pari + True + sage: J = O.ideal(y) # optional - sage.libs.pari + sage: I.valuation(J) # optional - sage.libs.pari + 2 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + [-1, 2] + + The method closely follows Algorithm 4.8.17 of [Coh1993]_. + """ + from sage.matrix.constructor import matrix + + if ideal.is_zero(): + return infinity + + O = self.ring() + F = O.fraction_field() + n = F.degree() + + # beta_matrix is for fast multiplication with beta. For performance, + # this is computed here rather than when the prime is constructed. + if self._beta_matrix is None: + beta = self._beta + m = [] + for i in range(n): + mtable_row = O._mtable[i] + c = sum(beta[j] * mtable_row[j] for j in range(n)) + m.append(c) + self._beta_matrix = matrix(m) + + B = self._beta_matrix + + # Step 1: compute the valuation of the denominator times the ideal + # + # This part is highly optimized as it is critical for + # overall performance of the function field machinery. + p = self.prime_below().gen().numerator() + h = ideal._hnf.list() + val = min([c.valuation(p) for c in h]) + i = self._ramification_index * val + while True: + ppow = p ** val + h = (matrix(n, [c // ppow for c in h]) * B).list() + val = min([c.valuation(p) for c in h]) + if val.is_zero(): + break + i += self._ramification_index * (val - 1) + 1 + + # Step 2: compute the valuation of the denominator + j = self._ramification_index * ideal.denominator().valuation(p) + + # Step 3: return the valuation + return i - j + + def prime_below(self): + """ + Return the prime lying below this prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari + [Ideal (x) of Maximal order of Rational function field in x + over Finite Field of size 2, Ideal (x^2 + x + 1) of Maximal order + of Rational function field in x over Finite Field of size 2] + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari + [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, + Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] + + sage: K. = FunctionField(QQ); _. = K[] + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular + sage: O = F.maximal_order() # optional - sage.libs.singular + sage: I = O.ideal(y) # optional - sage.libs.singular + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.singular + [Ideal (x) of Maximal order of Rational function field in x over Rational Field, + Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Rational Field] + """ + return self._prime_below + + def _factor(self): + """ + Return the factorization of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I == I.factor().prod() # indirect doctest # optional - sage.libs.pari + True + """ + O = self.ring() + F = O.fraction_field() + o = F.base_field().maximal_order() + + # First we collect primes below self + d = self._denominator + i = d * self + + factors = [] + primes = set([o.ideal(p) for p,_ in d.factor()] + [p for p,_ in i.ideal_below().factor()]) + for prime in primes: + qs = [q[0] for q in O.decomposition(prime)] + for q in qs: + exp = q.valuation(self) + if exp != 0: + factors.append((q,exp)) + return factors + + +class FunctionFieldIdeal_global(FunctionFieldIdeal_polymod): + """ + Fractional ideals of canonical function fields + + INPUT: + + - ``ring`` -- order in a function field + + - ``hnf`` -- matrix in hermite normal form + + - ``denominator`` -- denominator + + The rows of ``hnf`` is a basis of the ideal, which itself is + ``denominator`` times the fractional ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.ideal(y) # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x + """ + def __init__(self, ring, hnf, denominator=1): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(5)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari + """ + FunctionFieldIdeal_polymod.__init__(self, ring, hnf, denominator) + + def __pow__(self, mod): + """ + Return ``self`` to the power of ``mod``. + + If a two-generators representation of ``self`` is known, it is used + to speed up powering. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^7 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari + sage: S = I / J # optional - sage.libs.pari + sage: a = S^100 # optional - sage.libs.pari + sage: _ = S.gens_two() # optional - sage.libs.pari + sage: b = S^100 # faster # optional - sage.libs.pari + sage: b == I^100 / J^100 # optional - sage.libs.pari + True + sage: b == a # optional - sage.libs.pari + True + """ + if mod > 2 and self._gens_two_vecs is not None: + O = self._ring + mul = O._mul_vecs + R = self._hnf.base_ring() + n = self._hnf.ncols() + + I = matrix.identity(R, n) + + if len(self._gens_two_vecs) == 1: + p, = self._gens_two_vecs + ppow = p**mod + J = [ppow * v for v in I] + else: + p, q = self._gens_two_vecs + q = sum(e1 * e2 for e1,e2 in zip(O.basis(), q)) + ppow = p**mod + qpow = O._coordinate_vector(q**mod) + J = [ppow * v for v in I] + [mul(qpow,v) for v in I] + + return O._ideal_from_vectors_and_denominator(J, self._denominator**mod) + + return generic_power(self, mod) + + def gens(self): + """ + Return a set of generators of this ideal. + + This provides whatever set of generators as quickly + as possible. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^4 + x^2 + x, y + x) + + sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^3 + 1, y + x) + """ + if self._gens_two.is_in_cache(): + return self._gens_two.cache + else: + return self.gens_over_base() + + def gens_two(self): + r""" + Return two generators of this fractional ideal. + + If the ideal is principal, one generator *may* be returned. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I # indirect doctest # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field + in y defined by y^3 + x^6 + x^4 + x^2 + sage: ~I # indirect doctest # optional - sage.libs.pari + Ideal ((1/(x^6 + x^4 + x^2))*y^2) of Maximal order of Function field + in y defined by y^3 + x^6 + x^4 + x^2 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y) # optional - sage.libs.pari + sage: I # indirect doctest # optional - sage.libs.pari + Ideal (y) of Maximal order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + sage: ~I # indirect doctest # optional - sage.libs.pari + Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order + of Function field in y defined by y^2 + y + (x^2 + 1)/x + """ + d = self.denominator() + return tuple(e/d for e in self._gens_two()) + + @cached_method + def _gens_two(self): + r""" + Return a set of two generators of the integral ideal, that is + the denominator times this fractional ideal. + + ALGORITHM: + + At most two generators are required to generate ideals in + Dedekind domains. + + Lemma 4.7.9, algorithm 4.7.10, and exercise 4.29 of [Coh1993]_ + tell us that for an integral ideal `I` in a number field, if + we pick `a` such that `\gcd(N(I), N(a)/N(I)) = 1`, then `a` + and `N(I)` generate the ideal. `N()` is the norm, and this + result (presumably) generalizes to function fields. + + After computing `N(I)`, we search exhaustively to find `a`. + + .. TODO:: + + Always return a single generator for a principal ideal. + + Testing for principality is not trivial. Algorithm 6.5.10 + of [Coh1993]_ could probably be adapted for function fields. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2,x*y,x+y) # optional - sage.libs.pari + sage: I._gens_two() # optional - sage.libs.pari + (x, y) + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y-x) # optional - sage.libs.pari + sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.libs.pari + (x,) + """ + O = self.ring() + F = O.fraction_field() + + if self._kummer_form is not None: # prime ideal + _g1, _g2 = self._kummer_form + g1 = F(_g1) + g2 = sum([c1*c2 for c1,c2 in zip(_g2, O.basis())]) + if g2: + self._gens_two_vecs = (_g1, _g2) + return (g1,g2) + else: + self._gens_two_vecs = (_g1,) + return (g1,) + + ### start to search for two generators + + hnf = self._hnf + + norm = 1 + for e in hnf.diagonal(): + norm *= e + + if norm.is_constant(): # unit ideal + self._gens_two_vecs = (1,) + return (F(1),) + + # one generator; see .ideal_below() + _l = hnf[0][0] + p = _l.degree() + l = F(_l) + + if self._hnf == O.ideal(l)._hnf: # principal ideal + self._gens_two_vecs = (_l,) + return (l,) + + R = hnf.base_ring() + + basis = [] + for row in hnf: + basis.append(sum([c1*c2 for c1,c2 in zip(row, O.basis())])) + + n = len(basis) + alpha = None + + def check(alpha): + alpha_norm = alpha.norm().numerator() # denominator is 1 + return norm.gcd(alpha_norm // norm) == 1 + + # Trial 1: search for alpha among generators + for alpha in basis: + if check(alpha): + self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) + return (l, alpha) + + # Trial 2: exhaustive search for alpha using only polynomials + # with coefficients 0 or 1 + for d in range(p): + G = itertools.product(itertools.product([0,1],repeat=d+1), repeat=n) + for g in G: + alpha = sum([R(c1)*c2 for c1,c2 in zip(g, basis)]) + if check(alpha): + self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) + return (l, alpha) + + # Trial 3: exhaustive search for alpha using all polynomials + for d in range(p): + G = itertools.product(R.polynomials(max_degree=d), repeat=n) + for g in G: + # discard duplicate cases + if max(c.degree() for c in g) != d: + continue + for j in range(n): + if g[j] != 0: + break + if g[j].leading_coefficient() != 1: + continue + + alpha = sum([c1*c2 for c1,c2 in zip(g, basis)]) + if check(alpha): + self._gens_two_vecs = (_l, O._coordinate_vector(alpha)) + return (l, alpha) + + # should not reach here + raise ValueError("no two generators found") + + +class FunctionFieldIdealInfinite_polymod(FunctionFieldIdealInfinite): + """ + Ideals of the infinite maximal order of an algebraic function field. + + INPUT: + + - ``ring`` -- infinite maximal order of the function field + + - ``ideal`` -- ideal in the inverted function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(1/y) # optional - sage.libs.pari + Ideal (1/x^4*y^2) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4 + """ + def __init__(self, ring, ideal): + """ + Initialize this ideal. + + TESTS:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari + """ + FunctionFieldIdealInfinite.__init__(self, ring) + self._ideal = ideal + + def __hash__(self): + """ + Return the hash of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: d = { I: 1 } # optional - sage.libs.pari + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: d = { I: 1 } # optional - sage.libs.pari + """ + return hash((self.ring(), self._ideal)) + + def __contains__(self, x): + """ + Return ``True`` if ``x`` is in this ideal. + + INPUT: + + - ``x`` -- element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari + sage: 1/y in I # optional - sage.libs.pari + True + sage: 1/x in I # optional - sage.libs.pari + False + sage: 1/x^2 in I # optional - sage.libs.pari + True + """ + F = self.ring().fraction_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + return to_iF(x) in self._ideal + + def _add_(self, other): + """ + Add this ideal with the ``other`` ideal. + + INPUT: + + - ``ideal`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari + Ideal (1/x) of Maximal infinite order of Function field in y + defined by y^3 + y^2 + 2*x^4 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari + Ideal (1/x) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + """ + return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal + other._ideal) + + def _mul_(self, other): + """ + Multiply this ideal with the ``other`` ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari + Ideal (1/x^7*y^2) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari + Ideal (1/x^4*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + """ + return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal * other._ideal) + + def __pow__(self, n): + """ + Raise this ideal to ``n``-th power. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: J^3 # optional - sage.libs.pari + Ideal (1/x^3) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4 + """ + return FunctionFieldIdealInfinite_polymod(self._ring, self._ideal ** n) + + def __invert__(self): + """ + Return the inverted ideal of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(y) # optional - sage.libs.pari + sage: ~J # optional - sage.libs.pari + Ideal (1/x^4*y^2) of Maximal infinite order + of Function field in y defined by y^3 + y^2 + 2*x^4 + sage: J * ~J # optional - sage.libs.pari + Ideal (1) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: J = Oinf.ideal(y) # optional - sage.libs.pari + sage: ~J # optional - sage.libs.pari + Ideal (1/x*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + sage: J * ~J # optional - sage.libs.pari + Ideal (1) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x + """ + return FunctionFieldIdealInfinite_polymod(self._ring, ~ self._ideal) + + def _richcmp_(self, other, op): + """ + Compare this ideal with the ``other`` ideal with respect to ``op``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J == J * I # optional - sage.libs.pari + True + sage: I + J == J # optional - sage.libs.pari + True + sage: I + J == I # optional - sage.libs.pari + False + sage: (I < J) == (not J < I) # optional - sage.libs.pari + True + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I * J == J * I # optional - sage.libs.pari + True + sage: I + J == J # optional - sage.libs.pari + True + sage: I + J == I # optional - sage.libs.pari + False + sage: (I < J) == (not J < I) # optional - sage.libs.pari + True + """ + return richcmp(self._ideal, other._ideal, op) + + @property + def _relative_degree(self): + """ + Return the relative degree of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: [J._relative_degree for J,_ in I.factor()] # optional - sage.libs.pari + [1] + """ + if not self.is_prime(): + raise TypeError("not a prime ideal") + + return self._ideal._relative_degree + + def gens(self): + """ + Return a set of generators of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x, y, 1/x^2*y^2) + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x, y) + """ + F = self.ring().fraction_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + return tuple(from_iF(b) for b in self._ideal.gens()) + + def gens_two(self): + """ + Return a set of at most two generators of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_two() # optional - sage.libs.pari + (x, y) + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2+Y+x+1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I.gens_two() # optional - sage.libs.pari + (x,) + """ + F = self.ring().fraction_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + return tuple(from_iF(b) for b in self._ideal.gens_two()) + + def gens_over_base(self): + """ + Return a set of generators of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari + (x, y, 1/x^2*y^2) + """ + F = self.ring().fraction_field() + iF,from_iF,to_iF = F._inversion_isomorphism() + return tuple(from_iF(g) for g in self._ideal.gens_over_base()) + + def ideal_below(self): + """ + Return a set of generators of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/y^2) # optional - sage.libs.pari + sage: I.ideal_below() # optional - sage.libs.pari + Ideal (x^3) of Maximal order of Rational function field + in x over Finite Field in z2 of size 3^2 + """ + return self._ideal.ideal_below() + + def is_prime(self): + """ + Return ``True`` if this ideal is a prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari + (Ideal (1/x^3*y^2) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4)^3 + sage: I.is_prime() # optional - sage.libs.pari + False + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari + True + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari + (Ideal (1/x*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x)^2 + sage: I.is_prime() # optional - sage.libs.pari + False + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari + True + """ + return self._ideal.is_prime() + + @cached_method + def prime_below(self): + """ + Return the prime of the base order that underlies this prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari + (Ideal (1/x^3*y^2) of Maximal infinite order of Function field + in y defined by y^3 + y^2 + 2*x^4)^3 + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari + True + sage: J.prime_below() # optional - sage.libs.pari + Ideal (1/x) of Maximal infinite order of Rational function field + in x over Finite Field in z2 of size 3^2 + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari + (Ideal (1/x*y) of Maximal infinite order of Function field in y + defined by y^2 + y + (x^2 + 1)/x)^2 + sage: J = I.factor()[0][0] # optional - sage.libs.pari + sage: J.is_prime() # optional - sage.libs.pari + True + sage: J.prime_below() # optional - sage.libs.pari + Ideal (1/x) of Maximal infinite order of Rational function field in x + over Finite Field of size 2 + """ + if not self.is_prime(): + raise TypeError("not a prime ideal") + + F = self.ring().fraction_field() + K = F.base_field() + return K.maximal_order_infinite().prime_ideal() + + def valuation(self, ideal): + """ + Return the valuation of ``ideal`` with respect to this prime ideal. + + INPUT: + + - ``ideal`` -- fractional ideal + + EXAMPLES:: + + sage: K.=FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(y) # optional - sage.libs.pari + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + [-1] + """ + if not self.is_prime(): + raise TypeError("not a prime ideal") + + return self._ideal.valuation(self.ring()._to_iF(ideal)) + + def _factor(self): + """ + Return factorization of the ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: f= 1/x # optional - sage.libs.pari + sage: I = Oinf.ideal(f) # optional - sage.libs.pari + sage: I._factor() # optional - sage.libs.pari + [(Ideal (1/x, 1/x^4*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y + defined by y^3 + x^6 + x^4 + x^2, 1), + (Ideal (1/x, 1/x^2*y + 1) of Maximal infinite order of Function field in y + defined by y^3 + x^6 + x^4 + x^2, 1)] + """ + if self._ideal.is_prime.is_in_cache() and self._ideal.is_prime(): + return [(self, 1)] + + O = self.ring() + factors = [] + for iprime, exp in O._to_iF(self).factor(): + prime = FunctionFieldIdealInfinite_polymod(O, iprime) + factors.append((prime, exp)) + return factors + + diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py new file mode 100644 index 00000000000..9bad335cc02 --- /dev/null +++ b/src/sage/rings/function_field/ideal_rational.py @@ -0,0 +1,605 @@ +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.richcmp import richcmp +from sage.rings.infinity import infinity + +from .ideal import FunctionFieldIdeal, FunctionFieldIdealInfinite + + +class FunctionFieldIdeal_rational(FunctionFieldIdeal): + """ + Fractional ideals of the maximal order of a rational function field. + + INPUT: + + - ``ring`` -- the maximal order of the rational function field. + + - ``gen`` -- generator of the ideal, an element of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(1/(x^2+x)); I + Ideal (1/(x^2 + x)) of Maximal order of Rational function field in x over Rational Field + """ + def __init__(self, ring, gen): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(1/(x^2+x)) + sage: TestSuite(I).run() + """ + FunctionFieldIdeal.__init__(self, ring) + self._gen = gen + + def __hash__(self): + """ + Return the hash computed from the data. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(1/(x^2+x)) + sage: d = { I: 1, I^2: 2 } + """ + return hash( (self._ring, self._gen) ) + + def __contains__(self, element): + """ + Test if ``element`` is in this ideal. + + INPUT: + + - ``element`` -- element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(1/(x+1)) + sage: x in I + True + """ + return (element / self._gen) in self._ring + + def _richcmp_(self, other, op): + """ + Compare the element with the other element with respect + to the comparison operator. + + INPUT: + + - ``other`` -- element + + - ``op`` -- comparison operator + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x,x^2+1) + sage: J = O.ideal(x^2+x+1,x) + sage: I == J + True + sage: I = O.ideal(x) + sage: J = O.ideal(x+1) + sage: I < J + True + """ + return richcmp(self._gen, other._gen, op) + + def _add_(self, other): + """ + Add this ideal with the ``other`` ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x,x^2+1) + sage: J = O.ideal(x^2+x+1,x) + sage: I + J == J + I + True + """ + return self._ring.ideal([self._gen, other._gen]) + + def _mul_(self, other): + """ + Multiply this ideal with the ``other`` ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x,x^2+x) + sage: J = O.ideal(x^2,x) + sage: I * J == J * I + True + """ + return self._ring.ideal([self._gen * other._gen]) + + def _acted_upon_(self, other, on_left): + """ + Multiply ``other`` with this ideal on the right. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x^3+x^2) + sage: 2 * I + Ideal (x^3 + x^2) of Maximal order of Rational function field in x over Rational Field + sage: x * I + Ideal (x^4 + x^3) of Maximal order of Rational function field in x over Rational Field + """ + return self._ring.ideal([other * self._gen]) + + def __invert__(self): + """ + Return the ideal inverse of this fractional ideal. + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: I = O.ideal(x/(x^2+1)) + sage: ~I + Ideal ((x^2 + 1)/x) of Maximal order of Rational function field + in x over Rational Field + """ + return self._ring.ideal([~(self._gen)]) + + def denominator(self): + """ + Return the denominator of this fractional ideal. + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: I = O.ideal(x/(x^2+1)) + sage: I.denominator() + x^2 + 1 + """ + return self._gen.denominator() + + def is_prime(self): + """ + Return ``True`` if this is a prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x^3 + x^2) + sage: [f.is_prime() for f,m in I.factor()] # optional - sage.libs.pari + [True, True] + """ + return self._gen.denominator() == 1 and self._gen.numerator().is_prime() + + @cached_method + def module(self): + """ + Return the module, that is the ideal viewed as a module over the ring. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order() + sage: I = O.ideal(x^3+x^2) + sage: I.module() # optional - sage.modules + Free module of degree 1 and rank 1 over Maximal order of Rational + function field in x over Rational Field + Echelon basis matrix: + [x^3 + x^2] + sage: J = 0*I + sage: J.module() # optional - sage.modules + Free module of degree 1 and rank 0 over Maximal order of Rational + function field in x over Rational Field + Echelon basis matrix: + [] + """ + V, fr, to = self.ring().fraction_field().vector_space() + return V.span([to(g) for g in self.gens()], base_ring=self.ring()) + + def gen(self): + """ + Return the unique generator of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gen() # optional - sage.libs.pari + x^2 + x + """ + return self._gen + + def gens(self): + """ + Return the tuple of the unique generator of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (x^2 + x,) + """ + return (self._gen,) + + def gens_over_base(self): + """ + Return the generator of this ideal as a rank one module over the maximal + order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari + (x^2 + x,) + """ + return (self._gen,) + + def valuation(self, ideal): + """ + Return the valuation of the ideal at this prime ideal. + + INPUT: + + - ``ideal`` -- fractional ideal + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: I = O.ideal(x^2*(x^2+x+1)^3) + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + [2, 3] + """ + if not self.is_prime(): + raise TypeError("not a prime ideal") + + O = self.ring() + d = ideal.denominator() + return self._valuation(d*ideal) - self._valuation(O.ideal(d)) + + def _valuation(self, ideal): + """ + Return the valuation of the integral ideal at this prime ideal. + + INPUT: + + - ``ideal`` -- ideal + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order() + sage: p = O.ideal(x) + sage: p.valuation(O.ideal(x+1)) # indirect doctest + 0 + sage: p.valuation(O.ideal(x^2)) # indirect doctest + 2 + sage: p.valuation(O.ideal(1/x^3)) # indirect doctest + -3 + sage: p.valuation(O.ideal(0)) # indirect doctest + +Infinity + """ + return ideal.gen().valuation(self.gen()) + + def _factor(self): + """ + Return the list of prime and multiplicity pairs of the + factorization of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^3*(x+1)^2) # optional - sage.libs.pari + sage: I.factor() # indirect doctest # optional - sage.libs.pari + (Ideal (x) of Maximal order of Rational function field in x + over Finite Field in z2 of size 2^2)^3 * + (Ideal (x + 1) of Maximal order of Rational function field in x + over Finite Field in z2 of size 2^2)^2 + """ + return [(self.ring().ideal(f), m) for f, m in self._gen.factor()] + + +class FunctionFieldIdealInfinite_rational(FunctionFieldIdealInfinite): + """ + Fractional ideal of the maximal order of rational function field. + + INPUT: + + - ``ring`` -- infinite maximal order + + - ``gen``-- generator + + Note that the infinite maximal order is a principal ideal domain. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ideal(x) # optional - sage.libs.pari + Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 + """ + def __init__(self, ring, gen): + """ + Initialize. + + TESTS:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x) # optional - sage.libs.pari + sage: TestSuite(I).run() # optional - sage.libs.pari + """ + FunctionFieldIdealInfinite.__init__(self, ring) + self._gen = gen + + def __hash__(self): + """ + Return the hash of this fractional ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari + sage: d = { I: 1, J: 2 } # optional - sage.libs.pari + """ + return hash( (self.ring(), self._gen) ) + + def __contains__(self, element): + """ + Test if ``element`` is in this ideal. + + INPUT: + + - ``element`` -- element of the function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: O = K.maximal_order_infinite() + sage: I = O.ideal(1/(x+1)) + sage: x in I + False + sage: 1/x in I + True + sage: x/(x+1) in I + False + sage: 1/(x*(x+1)) in I + True + """ + return (element / self._gen) in self._ring + + def _richcmp_(self, other, op): + """ + Compare this ideal and ``other`` with respect to ``op``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x+1) # optional - sage.libs.pari + sage: J = Oinf.ideal(x^2+x) # optional - sage.libs.pari + sage: I + J == J # optional - sage.libs.pari + True + """ + return richcmp(self._gen, other._gen, op) + + def _add_(self, other): + """ + Add this ideal with the other ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari + sage: I + J # optional - sage.libs.pari + Ideal (1/x) of Maximal infinite order of Rational function field + in x over Finite Field of size 2 + """ + return self._ring.ideal([self._gen, other._gen]) + + def _mul_(self, other): + """ + Multiply this ideal with the ``other`` ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari + sage: I * J # optional - sage.libs.pari + Ideal (1/x^2) of Maximal infinite order of Rational function field + in x over Finite Field of size 2 + """ + return self._ring.ideal([self._gen * other._gen]) + + def _acted_upon_(self, other, on_left): + """ + Multiply this ideal with the ``other`` ideal. + + INPUT: + + - ``other`` -- ideal + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari + sage: x * I # optional - sage.libs.pari + Ideal (1) of Maximal infinite order of Rational function field + in x over Finite Field of size 2 + """ + return self._ring.ideal([other * self._gen]) + + def __invert__(self): + """ + Return the multiplicative inverse of this ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari + sage: ~I # indirect doctest # optional - sage.libs.pari + Ideal (x) of Maximal infinite order of Rational function field in x + over Finite Field of size 2 + """ + return self._ring.ideal([~self._gen]) + + def is_prime(self): + """ + Return ``True`` if this ideal is a prime ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.libs.pari + True + """ + x = self._ring.fraction_field().gen() + return self._gen == 1/x + + def gen(self): + """ + Return the generator of this principal ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gen() # optional - sage.libs.pari + 1/x^2 + """ + return self._gen + + def gens(self): + """ + Return the generator of this principal ideal. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gens() # optional - sage.libs.pari + (1/x^2,) + """ + return (self._gen,) + + def gens_over_base(self): + """ + Return the generator of this ideal as a rank one module + over the infinite maximal order. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I.gens_over_base() # optional - sage.libs.pari + (1/x^2,) + """ + return (self._gen,) + + def valuation(self, ideal): + """ + Return the valuation of ``ideal`` at this prime ideal. + + INPUT: + + - ``ideal`` -- fractional ideal + + EXAMPLES:: + + sage: F. = FunctionField(QQ) + sage: O = F.maximal_order_infinite() + sage: p = O.ideal(1/x) + sage: p.valuation(O.ideal(x/(x+1))) + 0 + sage: p.valuation(O.ideal(0)) + +Infinity + """ + if not self.is_prime(): + raise TypeError("not a prime ideal") + + f = ideal.gen() + if f == 0: + return infinity + else: + return f.denominator().degree() - f.numerator().degree() + + def _factor(self): + """ + Return the factorization of this ideal into prime ideals. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+1)) # optional - sage.libs.pari + sage: I._factor() # optional - sage.libs.pari + [(Ideal (1/x) of Maximal infinite order of Rational function field in x + over Finite Field of size 2, 2)] + """ + g = ~(self.ring().fraction_field().gen()) + m = self._gen.denominator().degree() - self._gen.numerator().degree() + if m == 0: + return [] + else: + return [(self.ring().ideal(g), m)] + + diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py new file mode 100644 index 00000000000..06129286b1e --- /dev/null +++ b/src/sage/rings/function_field/place_polymod.py @@ -0,0 +1,663 @@ + +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +import sage +from sage.arith.functions import lcm +from sage.rings.integer_ring import ZZ +from sage.misc.cachefunc import cached_method +from sage.rings.number_field.number_field_base import NumberField + +from .place import FunctionFieldPlace + + +class FunctionFieldPlace_polymod(FunctionFieldPlace): + """ + Places of extensions of function fields. + """ + def place_below(self): + """ + Return the place lying below the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.place_below() # optional - sage.libs.pari + Place (x^2 + x + 1) + """ + return self.prime_ideal().prime_below().place() + + def relative_degree(self): + """ + Return the relative degree of the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.relative_degree() # optional - sage.libs.pari + 1 + """ + return self._prime._relative_degree + + def degree(self): + """ + Return the degree of the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: OK = K.maximal_order() # optional - sage.libs.pari + sage: OL = L.maximal_order() # optional - sage.libs.pari + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: dec = OL.decomposition(p) # optional - sage.libs.pari + sage: q = dec[0][0].place() # optional - sage.libs.pari + sage: q.degree() # optional - sage.libs.pari + 2 + """ + return self.relative_degree() * self.place_below().degree() + + def is_infinite_place(self): + """ + Return ``True`` if the place is above the unique infinite place + of the underlying rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: pls = L.places() # optional - sage.libs.pari + sage: [p.is_infinite_place() for p in pls] # optional - sage.libs.pari + [True, True, False] + sage: [p.place_below() for p in pls] # optional - sage.libs.pari + [Place (1/x), Place (1/x), Place (x)] + """ + return self.place_below().is_infinite_place() + + def local_uniformizer(self): + """ + Return an element of the function field that has a simple zero + at the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: pls = L.places() # optional - sage.libs.pari + sage: [p.local_uniformizer().valuation(p) for p in pls] # optional - sage.libs.pari + [1, 1, 1, 1, 1] + """ + gens = self._prime.gens() + for g in gens: + if g.valuation(self) == 1: + return g + assert False, "Internal error" + + def gaps(self): + """ + Return the gap sequence for the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p.gaps() # a Weierstrass place # optional - sage.libs.pari + [1, 2, 4] + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: [p.gaps() for p in L.places()] # optional - sage.libs.pari + [[1, 2, 4], [1, 2, 4], [1, 2, 4]] + """ + if self.degree() == 1: + return self._gaps_rational() # faster for rational places + else: + return self._gaps_wronskian() + + def _gaps_rational(self): + """ + Return the gap sequence for the rational place. + + This method computes the gap numbers using the definition of gap + numbers. The dimension of the multiple of the prime divisor + supported at the place is computed by Hess' algorithm. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p.gaps() # indirect doctest # optional - sage.libs.pari + [1, 2, 4] + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.libs.pari + [[1, 2, 4], [1, 2, 4], [1, 2, 4]] + """ + from sage.matrix.constructor import matrix + + F = self.function_field() + n = F.degree() + O = F.maximal_order() + Oinf = F.maximal_order_infinite() + + R = O._module_base_ring._ring + one = R.one() + + # Hess' Riemann-Roch basis algorithm stripped down for gaps computation + def dim_RR(M): + den = lcm([e.denominator() for e in M.list()]) + mat = matrix(R, M.nrows(), [(den*e).numerator() for e in M.list()]) + + # initialise pivot_row and conflicts list + pivot_row = [[] for i in range(n)] + conflicts = [] + for i in range(n): + bestp = -1 + best = -1 + for c in range(n): + d = mat[i,c].degree() + if d >= best: + bestp = c + best = d + + if best >= 0: + pivot_row[bestp].append((i,best)) + if len(pivot_row[bestp]) > 1: + conflicts.append(bestp) + + # while there is a conflict, do a simple transformation + while conflicts: + c = conflicts.pop() + row = pivot_row[c] + i,ideg = row.pop() + j,jdeg = row.pop() + + if jdeg > ideg: + i,j = j,i + ideg,jdeg = jdeg,ideg + + coeff = - mat[i,c].lc() / mat[j,c].lc() + s = coeff * one.shift(ideg - jdeg) + + mat.add_multiple_of_row(i, j, s) + + row.append((j,jdeg)) + + bestp = -1 + best = -1 + for c in range(n): + d = mat[i,c].degree() + if d >= best: + bestp = c + best = d + + if best >= 0: + pivot_row[bestp].append((i,best)) + if len(pivot_row[bestp]) > 1: + conflicts.append(bestp) + + dim = 0 + for j in range(n): + i,ideg = pivot_row[j][0] + k = den.degree() - ideg + 1 + if k > 0: + dim += k + return dim + + V,fr,to = F.vector_space() + + prime_inv = ~ self.prime_ideal() + I = O.ideal(1) + J = Oinf.ideal(1) + + B = matrix([to(b) for b in J.gens_over_base()]) + C = matrix([to(v) for v in I.gens_over_base()]) + + prev = dim_RR(C * B.inverse()) + gaps = [] + g = F.genus() + i = 1 + if self.is_infinite_place(): + while g: + J = J * prime_inv + B = matrix([to(b) for b in J.gens_over_base()]) + dim = dim_RR(C * B.inverse()) + if dim == prev: + gaps.append(i) + g -= 1 + else: + prev = dim + i += 1 + else: # self is a finite place + Binv = B.inverse() + while g: + I = I * prime_inv + C = matrix([to(v) for v in I.gens_over_base()]) + dim = dim_RR(C * Binv) + if dim == prev: + gaps.append(i) + g -= 1 + else: + prev = dim + i += 1 + + return gaps + + def _gaps_wronskian(self): + """ + Return the gap sequence for the place. + + This method implements the local version of Hess' Algorithm 30 of [Hes2002b]_ + based on the Wronskian determinant. + + EXAMPLES:: + + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari + [1, 2, 4] + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari + sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.libs.pari + [[1, 2, 4], [1, 2, 4], [1, 2, 4]] + """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + F = self.function_field() + R,fr_R,to_R = self._residue_field() + der = F.higher_derivation() + + sep = self.local_uniformizer() + + # a differential divisor satisfying + # v_p(W) = 0 for the place p + W = sep.differential().divisor() + + # Step 3: + basis = W._basis() + d = len(basis) + M = matrix([to_R(b) for b in basis]) + if M.rank() == 0: + return [] + + # Steps 4, 5, 6, 7: + e = 1 + gaps = [1] + while M.nrows() < d: + row = vector([to_R(der._derive(basis[i], e, sep)) for i in range(d)]) + if row not in M.row_space(): + M = matrix(M.rows() + [row]) + M.echelonize() + gaps.append(e + 1) + e += 1 + + return gaps + + def residue_field(self, name=None): + """ + Return the residue field of the place. + + INPUT: + + - ``name`` -- string; name of the generator of the residue field + + OUTPUT: + + - a field isomorphic to the residue field + + - a ring homomorphism from the valuation ring to the field + + - a ring homomorphism from the field to the valuation ring + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari + Finite Field of size 2 + sage: fr_k # optional - sage.libs.pari + Ring morphism: + From: Finite Field of size 2 + To: Valuation ring at Place (x, x*y) + sage: to_k # optional - sage.libs.pari + Ring morphism: + From: Valuation ring at Place (x, x*y) + To: Finite Field of size 2 + sage: to_k(y) # optional - sage.libs.pari + Traceback (most recent call last): + ... + TypeError: y fails to convert into the map's domain + Valuation ring at Place (x, x*y)... + sage: to_k(1/y) # optional - sage.libs.pari + 0 + sage: to_k(y/(1+y)) # optional - sage.libs.pari + 1 + """ + return self.valuation_ring().residue_field(name=name) + + @cached_method + def _residue_field(self, name=None): + """ + Return the residue field of the place along with the functions + mapping from and to it. + + INPUT: + + - ``name`` -- string (default: `None`); name of the generator + of the residue field + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: k,fr_k,to_k = p._residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari + Finite Field of size 2 + sage: [fr_k(e) for e in k] # optional - sage.libs.pari + [0, 1] + + :: + + sage: K. = FunctionField(GF(9)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.pari + sage: p = L.places()[-1] # optional - sage.libs.pari + sage: p.residue_field() # optional - sage.libs.pari + (Finite Field in z2 of size 3^2, Ring morphism: + From: Finite Field in z2 of size 3^2 + To: Valuation ring at Place (x + 1, y + 2*z2), Ring morphism: + From: Valuation ring at Place (x + 1, y + 2*z2) + To: Finite Field in z2 of size 3^2) + + :: + + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular + sage: O = K.maximal_order() + sage: I = O.ideal(x) + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular + [(Rational Field, Ring morphism: + From: Rational Field + To: Valuation ring at Place (x, y, y^2), Ring morphism: + From: Valuation ring at Place (x, y, y^2) + To: Rational Field), + (Number Field in s with defining polynomial x^2 - 2*x + 2, Ring morphism: + From: Number Field in s with defining polynomial x^2 - 2*x + 2 + To: Valuation ring at Place (x, x*y, y^2 + 1), Ring morphism: + From: Valuation ring at Place (x, x*y, y^2 + 1) + To: Number Field in s with defining polynomial x^2 - 2*x + 2)] + sage: for p in L.places_above(I.place()): # optional - sage.libs.singular + ....: k, fr_k, to_k = p.residue_field() + ....: assert all(fr_k(k(e)) == e for e in range(10)) + ....: assert all(to_k(fr_k(e)) == e for e in [k.random_element() for i in [1..10]]) + + :: + + sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field + sage: I = O.ideal(x) # optional - sage.libs.singular sage.rings.number_field + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular sage.rings.number_field + [(Algebraic Field, Ring morphism: + From: Algebraic Field + To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: + From: Valuation ring at Place (x, y - I, y^2 + 1) + To: Algebraic Field), (Algebraic Field, Ring morphism: + From: Algebraic Field + To: Valuation ring at Place (x, y, y^2), Ring morphism: + From: Valuation ring at Place (x, y, y^2) + To: Algebraic Field), (Algebraic Field, Ring morphism: + From: Algebraic Field + To: Valuation ring at Place (x, y + I, y^2 + 1), Ring morphism: + From: Valuation ring at Place (x, y + I, y^2 + 1) + To: Algebraic Field)] + """ + F = self.function_field() + prime = self.prime_ideal() # Let P be this prime ideal + + if self.is_infinite_place(): + _F, from_F, to_F = F._inversion_isomorphism() + _prime = prime._ideal + _place = _prime.place() + + K, _from_K, _to_K = _place._residue_field(name=name) + + from_K = lambda e: from_F(_from_K(e)) + to_K = lambda f: _to_K(to_F(f)) + return K, from_K, to_K + + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + + O = F.maximal_order() + Obasis = O.basis() + + M = prime.hnf() + R = M.base_ring() # univariate polynomial ring + n = M.nrows() # extension degree of the function field + + # Step 1: construct a vector space representing the residue field + # + # Given an (reversed) HNF basis M for a prime ideal P of O, every + # element of O mod P can be represented by a vector of polynomials of + # degrees less than those of the (anti)diagonal elements of M. In turn, + # the vector of polynomials can be represented by the vector of the + # coefficients of the polynomials. V is the space of these vectors. + + k = F.constant_base_field() + degs = [M[i,i].degree() for i in range(n)] + deg = sum(degs) # degree of the place + + # Let V = k**deg + + def to_V(e): + """ + An example to show the idea: Suppose that:: + + [x 0 0] + M = [0 1 0] and v = (x^10, x^7 + x^3, x^7 + x^4 + x^3 + 1) + [1 0 1] + + Then to_V(e) = [1] + """ + v = O._coordinate_vector(e) + vec = [] + for i in reversed(range(n)): + q,r = v[i].quo_rem(M[i,i]) + v -= q * M[i] + for j in range(degs[i]): + vec.append(r[j]) + return vector(vec) + + def fr_V(vec): # to_O + vec = vec.list() + pos = 0 + e = F(0) + for i in reversed(range(n)): + if degs[i] == 0: + continue + else: + end = pos + degs[i] + e += R(vec[pos:end]) * Obasis[i] + pos = end + return e + + # Step 2: find a primitive element of the residue field + + def candidates(): + # Trial 1: this suffices for places obtained from Kummers' theorem + # and for places of function fields over number fields or QQbar + + # Note that a = O._kummer_gen is a simple generator of O/prime over + # o/p. If b is a simple generator of o/p over the constant base field + # k, then the set a + k * b contains a simple generator of O/prime + # over k (as there are finite number of intermediate fields). + a = O._kummer_gen + if a is not None: + K,fr_K,_ = self.place_below().residue_field() + b = fr_K(K.gen()) + if isinstance(k, (NumberField, sage.rings.abc.AlgebraicField)): + kk = ZZ + else: + kk = k + for c in kk: + if c != 0: + yield a + c * b + + # Trial 2: basis elements of the maximal order + for gen in reversed(Obasis): + yield gen + + import itertools + + # Trial 3: exhaustive search in O using only polynomials + # with coefficients 0 or 1 + for d in range(deg): + G = itertools.product(itertools.product([0,1],repeat=d+1), repeat=n) + for g in G: + gen = sum([R(c1)*c2 for c1,c2 in zip(g, Obasis)]) + yield gen + + # Trial 4: exhaustive search in O using all polynomials + for d in range(deg): + G = itertools.product(R.polynomials(max_degree=d), repeat=n) + for g in G: + # discard duplicate cases + if max(c.degree() for c in g) != d: + continue + for j in range(n): + if g[j] != 0: + break + if g[j].leading_coefficient() != 1: + continue + + gen = sum([c1*c2 for c1,c2 in zip(g, Obasis)]) + yield gen + + # Search for a primitive element. It is such an element g of O + # whose powers span the vector space V. + for gen in candidates(): + g = F.one() + m = [] + for i in range(deg): + m.append(to_V(g)) + g *= gen + mat = matrix(m) + if mat.rank() == deg: + break + + # Step 3: compute the minimal polynomial of g + min_poly = R((-mat.solve_left(to_V(g))).list() + [1]) + + # Step 4: construct the residue field K as an extension of the base + # constant field using the minimal polynomial and compute vector space + # representation W of K along with maps between them + if deg > 1: + if isinstance(k, NumberField): + if name is None: + name='s' + K = k.extension(min_poly, names=name) + + def from_W(e): + return K(list(e)) + + def to_W(e): + return vector(K(e)) + else: + K = k.extension(deg, name=name) + + # primitive element in K corresponding to g in O mod P + prim = min_poly.roots(K)[0][0] + + W, from_W, to_W = K.vector_space(k, basis=[prim**i for i in range(deg)], map=True) + else: # deg == 1 + K = k + + def from_W(e): + return K(e[0]) + + def to_W(e): + return vector([e]) + + # Step 5: compute the matrix of change of basis, from V to W via K + C = mat.inverse() + + # Step 6: construct the maps between the residue field of the valuation + # ring at P and K, via O and V and W + + def from_K(e): + return fr_V(to_W(e) * mat) + + # As explained in Section 4.8.3 of [Coh1993]_, alpha has a simple pole + # at this place and no other poles at finite places. + p = prime.prime_below().gen().numerator() + beta = prime._beta + alpha = ~p * sum(c1*c2 for c1,c2 in zip(beta, Obasis)) + alpha_powered_by_ramification_index = alpha ** prime._ramification_index + + def to_K(f): + if f not in O: + den = O.coordinate_vector(f).denominator() + num = den * f + + # s powered by the valuation of den at the prime + alpha_power = alpha_powered_by_ramification_index ** den.valuation(p) + rn = num * alpha_power # in O + rd = den * alpha_power # in O but not in prime + + # Note that rn is not in O if and only if f is + # not in the valuation ring. Hence f is in the + # valuation ring if and only if this procedure + # does not fall into an infinite loop. + return to_K(rn) / to_K(rd) + + return from_W(to_V(f) * C) + + return K, from_K, to_K + + def valuation_ring(self): + """ + Return the valuation ring at the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: p.valuation_ring() # optional - sage.libs.pari + Valuation ring at Place (x, x*y) + """ + from .valuation_ring import FunctionFieldValuationRing + + return FunctionFieldValuationRing(self.function_field(), self) + + diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py new file mode 100644 index 00000000000..74255ab086c --- /dev/null +++ b/src/sage/rings/function_field/place_rational.py @@ -0,0 +1,175 @@ + +#***************************************************************************** +# Copyright (C) 2023 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from .place import FunctionFieldPlace + + +class FunctionFieldPlace_rational(FunctionFieldPlace): + """ + Places of rational function fields. + """ + def degree(self): + """ + Return the degree of the place. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: p = i.place() # optional - sage.libs.pari + sage: p.degree() # optional - sage.libs.pari + 2 + """ + if self.is_infinite_place(): + return 1 + else: + return self._prime.gen().numerator().degree() + + def is_infinite_place(self): + """ + Return ``True`` if the place is at infinite. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari + [Place (1/x), Place (x), Place (x + 1)] + sage: [p.is_infinite_place() for p in F.places()] # optional - sage.libs.pari + [True, False, False] + """ + F = self.function_field() + return self.prime_ideal().ring() == F.maximal_order_infinite() + + def local_uniformizer(self): + """ + Return a local uniformizer of the place. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: F.places() # optional - sage.libs.pari + [Place (1/x), Place (x), Place (x + 1)] + sage: [p.local_uniformizer() for p in F.places()] # optional - sage.libs.pari + [1/x, x, x + 1] + """ + return self.prime_ideal().gen() + + def residue_field(self, name=None): + """ + Return the residue field of the place. + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari + sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari + sage: k # optional - sage.libs.pari + Finite Field in z2 of size 2^2 + sage: fr_k # optional - sage.libs.pari + Ring morphism: + From: Finite Field in z2 of size 2^2 + To: Valuation ring at Place (x^2 + x + 1) + sage: to_k # optional - sage.libs.pari + Ring morphism: + From: Valuation ring at Place (x^2 + x + 1) + To: Finite Field in z2 of size 2^2 + """ + return self.valuation_ring().residue_field(name=name) + + def _residue_field(self, name=None): + """ + Return the residue field of the place along with the maps from + and to it. + + INPUT: + + - ``name`` -- string; name of the generator of the residue field + + EXAMPLES:: + + sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari + sage: p = i.place() # optional - sage.libs.pari + sage: R, fr, to = p._residue_field() # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Finite Field in z2 of size 2^2 + sage: [fr(e) for e in R.list()] # optional - sage.libs.pari + [0, x, x + 1, 1] + sage: to(x*(x+1)) == to(x) * to(x+1) # optional - sage.libs.pari + True + """ + F = self.function_field() + prime = self.prime_ideal() + + if self.is_infinite_place(): + K = F.constant_base_field() + + def from_K(e): + return F(e) + + def to_K(f): + n = f.numerator() + d = f.denominator() + + n_deg = n.degree() + d_deg =d.degree() + + if n_deg < d_deg: + return K(0) + elif n_deg == d_deg: + return n.lc() / d.lc() + else: + raise TypeError("not in the valuation ring") + else: + O = F.maximal_order() + K, from_K, _to_K = O._residue_field(prime, name=name) + + def to_K(f): + if f in O: # f.denominator() is 1 + return _to_K(f.numerator()) + else: + d = F(f.denominator()) + n = d * f + + nv = prime.valuation(O.ideal(n)) + dv = prime.valuation(O.ideal(d)) + + if nv > dv: + return K(0) + elif dv > nv: + raise TypeError("not in the valuation ring") + + s = ~prime.gen() + rd = d * s**dv # in O but not in prime + rn = n * s**nv # in O but not in prime + return to_K(rn) / to_K(rd) + + return K, from_K, to_K + + def valuation_ring(self): + """ + Return the valuation ring at the place. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: p = L.places_finite()[0] # optional - sage.libs.pari + sage: p.valuation_ring() # optional - sage.libs.pari + Valuation ring at Place (x, x*y) + """ + from .valuation_ring import FunctionFieldValuationRing + + return FunctionFieldValuationRing(self.function_field(), self) + + diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py new file mode 100644 index 00000000000..99ca4b76e29 --- /dev/null +++ b/src/sage/rings/function_field/valuation.py @@ -0,0 +1,1482 @@ +# -*- coding: utf-8 -*- +r""" +Discrete valuations on function fields + +AUTHORS: + +- Julian Rüth (2016-10-16): initial version + +EXAMPLES: + +We can create classical valuations that correspond to finite and infinite +places on a rational function field:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1); v + (x - 1)-adic valuation + sage: v = K.valuation(x^2 + 1); v + (x^2 + 1)-adic valuation + sage: v = K.valuation(1/x); v + Valuation at the infinite place + +Note that we can also specify valuations which do not correspond to a place of +the function field:: + + sage: R. = QQ[] + sage: w = valuations.GaussValuation(R, QQ.valuation(2)) + sage: v = K.valuation(w); v + 2-adic valuation + +Valuations on a rational function field can then be extended to finite +extensions:: + + sage: v = K.valuation(x - 1); v + (x - 1)-adic valuation + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: w = v.extensions(L); w # optional - sage.libs.singular + [[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation, + [ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation] + +TESTS: + +Run test suite for classical places over rational function fields:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1) + sage: TestSuite(v).run(max_runs=100) # long time + + sage: v = K.valuation(x^2 + 1) + sage: TestSuite(v).run(max_runs=100) # long time + + sage: v = K.valuation(1/x) + sage: TestSuite(v).run(max_runs=100) # long time + +Run test suite over classical places of finite extensions:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x - 1) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: ws = v.extensions(L) # optional - sage.libs.singular + sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # optional - sage.libs.singular + +Run test suite for valuations that do not correspond to a classical place:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: v = GaussValuation(R, QQ.valuation(2)) + sage: w = K.valuation(v) + sage: TestSuite(w).run() # long time + +Run test suite for a non-classical valuation that does not correspond to an +affinoid contained in the unit disk:: + + sage: w = K.valuation((w, K.hom(K.gen()/2), K.hom(2*K.gen()))); w + 2-adic valuation (in Rational function field in x over Rational Field after x |--> 1/2*x) + sage: TestSuite(w).run() # long time + +Run test suite for some other classical places over large ground fields:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: M. = FunctionField(K) # optional - sage.libs.pari + sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari + sage: TestSuite(v).run(max_runs=10) # long time # optional - sage.libs.pari + +Run test suite for extensions over the infinite place:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1/x) + sage: R. = K[] + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular + sage: w = v.extensions(L) # optional - sage.libs.singular + sage: TestSuite(w).run() # long time # optional - sage.libs.singular + +Run test suite for a valuation with `v(1/x) > 0` which does not come from a +classical valuation of the infinite place:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) + sage: w = K.valuation(w) + sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) + sage: TestSuite(v).run() # long time + +Run test suite for extensions which come from the splitting in the base field:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) + sage: L. = FunctionField(GaussianIntegers().fraction_field()) + sage: ws = v.extensions(L) # optional - sage.libs.singular + sage: for w in ws: TestSuite(w).run(max_runs=100) # long time + +Run test suite for a finite place with residual degree and ramification:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: L. = FunctionField(K) # optional - sage.libs.pari + sage: v = L.valuation(x^6 - t) # optional - sage.libs.pari + sage: TestSuite(v).run(max_runs=10) # long time + +Run test suite for a valuation which is backed by limit valuation:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x + 1)) + sage: v = K.valuation(x - 1) + sage: w = v.extension(L) # optional - sage.libs.singular + sage: TestSuite(w).run() # long time # optional - sage.libs.singular + +Run test suite for a valuation which sends an element to `-\infty`:: + + sage: R. = QQ[] + sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity) + sage: K. = FunctionField(QQ) + sage: w = K.valuation(v) + sage: TestSuite(w).run() # long time + +REFERENCES: + +An overview of some computational tools relating to valuations on function +fields can be found in Section 4.6 of [Rüt2014]_. Most of this was originally +developed for number fields in [Mac1936I]_ and [Mac1936II]_. + +""" +# **************************************************************************** +# Copyright (C) 2016-2018 Julian Rüth +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** +from sage.structure.factory import UniqueFactory +from sage.rings.rational_field import QQ +from sage.misc.cachefunc import cached_method + +from sage.rings.valuation.valuation import DiscreteValuation, DiscretePseudoValuation, InfiniteDiscretePseudoValuation, NegativeInfiniteDiscretePseudoValuation +from sage.rings.valuation.trivial_valuation import TrivialValuation +from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation, MappedValuation_base + +class FunctionFieldValuationFactory(UniqueFactory): + r""" + Create a valuation on ``domain`` corresponding to ``prime``. + + INPUT: + + - ``domain`` -- a function field + + - ``prime`` -- a place of the function field, a valuation on a subring, or + a valuation on another function field together with information for + isomorphisms to and from that function field + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1); v # indirect doctest + (x - 1)-adic valuation + sage: v(x) + 0 + sage: v(x - 1) + 1 + + See :meth:`sage.rings.function_field.function_field.FunctionField.valuation` for further examples. + + """ + def create_key_and_extra_args(self, domain, prime): + r""" + Create a unique key which identifies the valuation given by ``prime`` + on ``domain``. + + TESTS: + + We specify a valuation on a function field by two different means and + get the same object:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x - 1) # indirect doctest + + sage: R. = QQ[] + sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) + sage: K.valuation(w) is v + True + + The normalization is, however, not smart enough, to unwrap + substitutions that turn out to be trivial:: + + sage: w = GaussValuation(R, QQ.valuation(2)) + sage: w = K.valuation(w) + sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) + False + + """ + from sage.categories.function_fields import FunctionFields + if domain not in FunctionFields(): + raise ValueError("Domain must be a function field.") + + if isinstance(prime, tuple): + if len(prime) == 3: + # prime is a triple of a valuation on another function field with + # isomorphism information + return self.create_key_and_extra_args_from_valuation_on_isomorphic_field(domain, prime[0], prime[1], prime[2]) + + from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace + if prime.parent() is DiscretePseudoValuationSpace(domain): + # prime is already a valuation of the requested domain + # if we returned (domain, prime), we would break caching + # because this element has been created from a different key + # Instead, we return the key that was used to create prime + # so the caller gets back a correctly cached version of prime + if not hasattr(prime, "_factory_data"): + raise NotImplementedError("Valuations on function fields must be unique and come out of the FunctionFieldValuation factory but %r has been created by other means" % (prime,)) + return prime._factory_data[2], {} + + if prime in domain: + # prime defines a place + return self.create_key_and_extra_args_from_place(domain, prime) + if prime.parent() is DiscretePseudoValuationSpace(domain._ring): + # prime is a discrete (pseudo-)valuation on the polynomial ring + # that the domain is constructed from + return self.create_key_and_extra_args_from_valuation(domain, prime) + if domain.base_field() is not domain: + # prime might define a valuation on a subring of domain and have a + # unique extension to domain + base_valuation = domain.base_field().valuation(prime) + return self.create_key_and_extra_args_from_valuation(domain, base_valuation) + from sage.rings.ideal import is_Ideal + if is_Ideal(prime): + raise NotImplementedError("a place cannot be given by an ideal yet") + + raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r" % (prime, domain)) + + def create_key_and_extra_args_from_place(self, domain, generator): + r""" + Create a unique key which identifies the valuation at the place + specified by ``generator``. + + TESTS: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1/x) # indirect doctest + + """ + if generator not in domain.base_field(): + raise NotImplementedError("a place must be defined over a rational function field") + + if domain.base_field() is not domain: + # if this is an extension field, construct the unique place over + # the place on the subfield + return self.create_key_and_extra_args(domain, domain.base_field().valuation(generator)) + + if generator in domain.constant_base_field(): + # generator is a constant, we associate to it the place which + # corresponds to the polynomial (x - generator) + return self.create_key_and_extra_args(domain, domain.gen() - generator) + + if generator in domain._ring: + # generator is a polynomial + generator = domain._ring(generator) + if not generator.is_monic(): + raise ValueError("place must be defined by a monic polynomial but %r is not monic" % (generator,)) + if not generator.is_irreducible(): + raise ValueError("place must be defined by an irreducible polynomial but %r factors over %r" % (generator, domain._ring)) + # we construct the corresponding valuation on the polynomial ring + # with v(generator) = 1 + from sage.rings.valuation.gauss_valuation import GaussValuation + valuation = GaussValuation(domain._ring, TrivialValuation(domain.constant_base_field())).augmentation(generator, 1) + return self.create_key_and_extra_args(domain, valuation) + elif generator == ~domain.gen(): + # generator is 1/x, the infinite place + return (domain, (domain.valuation(domain.gen()), domain.hom(~domain.gen()), domain.hom(~domain.gen()))), {} + else: + raise ValueError("a place must be given by an irreducible polynomial or the inverse of the generator; %r does not define a place over %r" % (generator, domain)) + + def create_key_and_extra_args_from_valuation(self, domain, valuation): + r""" + Create a unique key which identifies the valuation which extends + ``valuation``. + + TESTS: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) + sage: v = K.valuation(w) # indirect doctest + + Check that :trac:`25294` has been resolved:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) # optional - sage.libs.singular + sage: v = K.valuation(x) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular + [[ (x)-adic valuation, v(y) = 1 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y), + [ (x)-adic valuation, v(y) = 1/2 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)] + + """ + # this should have been handled by create_key already + assert valuation.domain() is not domain + + if valuation.domain() is domain._ring: + if domain.base_field() is not domain: + vK = valuation.restriction(valuation.domain().base_ring()) + if vK.domain() is not domain.base_field(): + raise ValueError("valuation must extend a valuation on the base field but %r extends %r whose domain is not %r" % (valuation, vK, domain.base_field())) + # Valuation is an approximant that describes a single valuation + # on domain. + # For uniqueness of valuations (which provides better caching + # and easier pickling) we need to find a normal form of + # valuation, i.e., the smallest approximant that describes this + # valuation + approximants = vK.mac_lane_approximants(domain.polynomial(), require_incomparability=True) + approximant = vK.mac_lane_approximant(domain.polynomial(), valuation, approximants) + return (domain, approximant), {'approximants': approximants} + else: + # on a rational function field K(x), any valuation on K[x] that + # does not have an element with valuation -infty extends to a + # pseudo-valuation on K(x) + if valuation.is_negative_pseudo_valuation(): + raise ValueError("there must not be an element of valuation -Infinity in the domain of valuation %r" % (valuation,)) + return (domain, valuation), {} + + if valuation.domain().is_subring(domain.base_field()): + # valuation is defined on a subring of this function field, try to lift it + return self.create_key_and_extra_args(domain, valuation.extension(domain)) + + raise NotImplementedError("extension of valuation from %r to %r not implemented yet" % (valuation.domain(), domain)) + + def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, valuation, to_valuation_domain, from_valuation_domain): + r""" + Create a unique key which identifies the valuation which is + ``valuation`` after mapping through ``to_valuation_domain``. + + TESTS:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.libs.singular + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.libs.singular + sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.libs.singular + + """ + from sage.categories.function_fields import FunctionFields + if valuation.domain() not in FunctionFields(): + raise ValueError("valuation must be defined over an isomorphic function field but %r is not a function field" % (valuation.domain(),)) + + from sage.categories.homset import Hom + if to_valuation_domain not in Hom(domain, valuation.domain()): + raise ValueError("to_valuation_domain must map from %r to %r but %r maps from %r to %r" % (domain, valuation.domain(), to_valuation_domain, to_valuation_domain.domain(), to_valuation_domain.codomain())) + if from_valuation_domain not in Hom(valuation.domain(), domain): + raise ValueError("from_valuation_domain must map from %r to %r but %r maps from %r to %r" % (valuation.domain(), domain, from_valuation_domain, from_valuation_domain.domain(), from_valuation_domain.codomain())) + + if domain is domain.base(): + if valuation.domain() is not valuation.domain().base() or valuation.domain().constant_base_field() != domain.constant_base_field(): + raise NotImplementedError("maps must be isomorphisms with a rational function field over the same base field, not with %r" % (valuation.domain(),)) + if domain != valuation.domain(): + # make it harder to create different representations of the same valuation + # (nothing bad happens if we did, but >= and <= are only implemented when this is the case.) + raise NotImplementedError("domain and valuation.domain() must be the same rational function field but %r is not %r" % (domain, valuation.domain())) + else: + if domain.base() is not valuation.domain().base(): + raise NotImplementedError("domain and valuation.domain() must have the same base field but %r is not %r" % (domain.base(), valuation.domain().base())) + if to_valuation_domain != domain.hom([to_valuation_domain(domain.gen())]): + raise NotImplementedError("to_valuation_domain must be trivial on the base fields but %r is not %r" % (to_valuation_domain, domain.hom([to_valuation_domain(domain.gen())]))) + if from_valuation_domain != valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]): + raise NotImplementedError("from_valuation_domain must be trivial on the base fields but %r is not %r" % (from_valuation_domain, valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]))) + if to_valuation_domain(domain.gen()) == valuation.domain().gen(): + raise NotImplementedError("to_valuation_domain seems to be trivial but trivial maps would currently break partial orders of valuations") + + if from_valuation_domain(to_valuation_domain(domain.gen())) != domain.gen(): + # only a necessary condition + raise ValueError("to_valuation_domain and from_valuation_domain are not inverses of each other") + + return (domain, (valuation, to_valuation_domain, from_valuation_domain)), {} + + def create_object(self, version, key, **extra_args): + r""" + Create the valuation specified by ``key``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: w = valuations.GaussValuation(R, QQ.valuation(2)) + sage: v = K.valuation(w); v # indirect doctest + 2-adic valuation + + """ + domain, valuation = key + from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace + parent = DiscretePseudoValuationSpace(domain) + + if isinstance(valuation, tuple) and len(valuation) == 3: + valuation, to_valuation_domain, from_valuation_domain = valuation + if domain is domain.base() and valuation.domain() is valuation.domain().base(): + if valuation == valuation.domain().valuation(valuation.domain().gen()): + if to_valuation_domain != domain.hom([~valuation.domain().gen()]) or from_valuation_domain != valuation.domain().hom([~domain.gen()]): + raise ValueError("the only allowed automorphism for classical valuations is the automorphism x |--> 1/x") + # valuation on the rational function field after x |--> 1/x, + # i.e., the classical valuation at infinity + return parent.__make_element_class__(InfiniteRationalFunctionFieldValuation)(parent) + + from sage.structure.dynamic_class import dynamic_class + clazz = RationalFunctionFieldMappedValuation + if valuation.is_discrete_valuation(): + clazz = dynamic_class("RationalFunctionFieldMappedValuation_discrete", (clazz, DiscreteValuation)) + else: + clazz = dynamic_class("RationalFunctionFieldMappedValuation_infinite", (clazz, InfiniteDiscretePseudoValuation)) + return parent.__make_element_class__(clazz)(parent, valuation, to_valuation_domain, from_valuation_domain) + return parent.__make_element_class__(FunctionFieldExtensionMappedValuation)(parent, valuation, to_valuation_domain, from_valuation_domain) + + if domain is valuation.domain(): + # we cannot just return valuation in this case + # as this would break uniqueness and pickling + raise ValueError("valuation must not be a valuation on domain yet but %r is a valuation on %r" % (valuation, domain)) + + if domain.base_field() is domain: + # valuation is a base valuation on K[x] that induces a valuation on K(x) + if valuation.restriction(domain.constant_base_field()).is_trivial() and valuation.is_discrete_valuation(): + # valuation corresponds to a finite place + return parent.__make_element_class__(FiniteRationalFunctionFieldValuation)(parent, valuation) + else: + from sage.structure.dynamic_class import dynamic_class + clazz = NonClassicalRationalFunctionFieldValuation + if valuation.is_discrete_valuation(): + clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_discrete", (clazz, DiscreteFunctionFieldValuation_base)) + else: + clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_negative_infinite", (clazz, NegativeInfiniteDiscretePseudoValuation)) + return parent.__make_element_class__(clazz)(parent, valuation) + else: + # valuation is a limit valuation that singles out an extension + return parent.__make_element_class__(FunctionFieldFromLimitValuation)(parent, valuation, domain.polynomial(), extra_args['approximants']) + + raise NotImplementedError("valuation on %r from %r on %r" % (domain, valuation, valuation.domain())) + +FunctionFieldValuation = FunctionFieldValuationFactory("sage.rings.function_field.valuation.FunctionFieldValuation") + + +class FunctionFieldValuation_base(DiscretePseudoValuation): + r""" + Abstract base class for any discrete (pseudo-)valuation on a function + field. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) # indirect doctest + sage: from sage.rings.function_field.valuation import FunctionFieldValuation_base + sage: isinstance(v, FunctionFieldValuation_base) + True + + """ + + +class DiscreteFunctionFieldValuation_base(DiscreteValuation): + r""" + Base class for discrete valuations on function fields. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) # indirect doctest + sage: from sage.rings.function_field.valuation import DiscreteFunctionFieldValuation_base + sage: isinstance(v, DiscreteFunctionFieldValuation_base) + True + + """ + def extensions(self, L): + r""" + Return the extensions of this valuation to ``L``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) + sage: R. = K[] + sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular + [(x)-adic valuation] + + TESTS: + + Valuations over the infinite place:: + + sage: v = K.valuation(1/x) + sage: R. = K[] + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular + sage: sorted(v.extensions(L), key=str) # optional - sage.libs.singular + [[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation, + [ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation] + + Iterated extensions over the infinite place:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari + Traceback (most recent call last): + ... + NotImplementedError + + A case that caused some trouble at some point:: + + sage: R. = QQ[] + sage: v = GaussValuation(R, QQ.valuation(2)) + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(v) + + sage: R. = K[] + sage: L. = K.extension(y^3 - x^4 - 1) # optional - sage.libs.singular + sage: v.extensions(L) # optional - sage.libs.singular + [2-adic valuation] + + Test that this works in towers:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y - x) # optional - sage.libs.pari + sage: R. = L[] # optional - sage.libs.pari + sage: L. = L.extension(z - y) # optional - sage.libs.pari + sage: v = K.valuation(x) # optional - sage.libs.pari + sage: v.extensions(L) # optional - sage.libs.pari + [(x)-adic valuation] + """ + K = self.domain() + from sage.categories.function_fields import FunctionFields + if L is K: + return [self] + if L in FunctionFields(): + if K.is_subring(L): + if L.base() is K: + # L = K[y]/(G) is a simple extension of the domain of this valuation + G = L.polynomial() + if not G.is_monic(): + G = G / G.leading_coefficient() + if any(self(c) < 0 for c in G.coefficients()): + # rewrite L = K[u]/(H) with H integral and compute the extensions + from sage.rings.valuation.gauss_valuation import GaussValuation + g = GaussValuation(G.parent(), self) + y_to_u, u_to_y, H = g.monic_integral_model(G) + M = K.extension(H, names=L.variable_names()) + H_extensions = self.extensions(M) + + from sage.rings.morphism import RingHomomorphism_im_gens + if type(y_to_u) == RingHomomorphism_im_gens and type(u_to_y) == RingHomomorphism_im_gens: + return [L.valuation((w, L.hom([M(y_to_u(y_to_u.domain().gen()))]), M.hom([L(u_to_y(u_to_y.domain().gen()))]))) for w in H_extensions] + raise NotImplementedError + return [L.valuation(w) for w in self.mac_lane_approximants(L.polynomial(), require_incomparability=True)] + elif L.base() is not L and K.is_subring(L): + # recursively call this method for the tower of fields + from operator import add + from functools import reduce + A = [base_valuation.extensions(L) for base_valuation in self.extensions(L.base())] + return reduce(add, A, []) + elif L.constant_base_field() is not K.constant_base_field() and K.constant_base_field().is_subring(L): + # subclasses should override this method and handle this case, so we never get here + raise NotImplementedError("Cannot compute the extensions of %r from %r to %r since the base ring changes." % (self, self.domain(), L)) + raise NotImplementedError("extension of %r from %r to %r not implemented" % (self, K, L)) + + +class RationalFunctionFieldValuation_base(FunctionFieldValuation_base): + r""" + Base class for valuations on rational function fields. + + TESTS:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari + sage: from sage.rings.function_field.valuation import RationalFunctionFieldValuation_base + sage: isinstance(v, RationalFunctionFieldValuation_base) # optional - sage.libs.pari + True + + """ + @cached_method + def element_with_valuation(self, s): + r""" + Return an element with valuation ``s``. + + EXAMPLES:: + + sage: K. = NumberField(x^3+6) # optional - sage.rings.number_field + sage: v = K.valuation(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: w = GaussValuation(R, v).augmentation(x, 1/123) # optional - sage.rings.number_field + sage: K. = FunctionField(K) # optional - sage.rings.number_field + sage: w = w.extension(K) # optional - sage.rings.number_field + sage: w.element_with_valuation(122/123) # optional - sage.rings.number_field + 2/x + sage: w.element_with_valuation(1) # optional - sage.rings.number_field + 2 + + """ + constant_valuation = self.restriction(self.domain().constant_base_field()) + if constant_valuation.is_trivial(): + return super().element_with_valuation(s) + + a, b = self.value_group()._element_with_valuation(constant_valuation.value_group(), s) + ret = self.uniformizer()**a * constant_valuation.element_with_valuation(constant_valuation.value_group().gen()*b) + + return self.simplify(ret, error=s) + + +class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base): + r""" + Base class for discrete valuations on rational function fields that come + from points on the projective line. + + TESTS:: + + sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari + sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari + sage: from sage.rings.function_field.valuation import ClassicalFunctionFieldValuation_base + sage: isinstance(v, ClassicalFunctionFieldValuation_base) # optional - sage.libs.pari + True + + """ + def _test_classical_residue_field(self, **options): + r""" + Check correctness of the residue field of a discrete valuation at a + classical point. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) + sage: v._test_classical_residue_field() + + """ + tester = self._tester(**options) + + tester.assertTrue(self.domain().constant_base_field().is_subring(self.residue_field())) + + def _ge_(self, other): + r""" + Return whether ``self`` is greater or equal to ``other`` everywhere. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) + sage: w = K.valuation(x) + sage: v >= w + False + sage: w >= v + False + + """ + if other.is_trivial(): + return other.is_discrete_valuation() + if isinstance(other, ClassicalFunctionFieldValuation_base): + return self == other + super()._ge_(other) + + +class InducedRationalFunctionFieldValuation_base(FunctionFieldValuation_base): + r""" + Base class for function field valuation induced by a valuation on the + underlying polynomial ring. + + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) # indirect doctest + + """ + def __init__(self, parent, base_valuation): + r""" + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) # indirect doctest + sage: from sage.rings.function_field.valuation import InducedRationalFunctionFieldValuation_base + sage: isinstance(v, InducedRationalFunctionFieldValuation_base) + True + + """ + FunctionFieldValuation_base.__init__(self, parent) + + domain = parent.domain() + if base_valuation.domain() is not domain._ring: + raise ValueError("base valuation must be defined on %r but %r is defined on %r" % (domain._ring, base_valuation, base_valuation.domain())) + + self._base_valuation = base_valuation + + def uniformizer(self): + r""" + Return a uniformizing element for this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(x).uniformizer() + x + + """ + return self.domain()(self._base_valuation.uniformizer()) + + def lift(self, F): + r""" + Return a lift of ``F`` to the domain of this valuation such + that :meth:`reduce` returns the original element. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) + sage: v.lift(0) + 0 + sage: v.lift(1) + 1 + + """ + F = self.residue_ring().coerce(F) + if F in self._base_valuation.residue_ring(): + num = self._base_valuation.residue_ring()(F) + den = self._base_valuation.residue_ring()(1) + elif F in self._base_valuation.residue_ring().fraction_field(): + num = self._base_valuation.residue_ring()(F.numerator()) + den = self._base_valuation.residue_ring()(F.denominator()) + else: + raise NotImplementedError("lifting not implemented for this valuation") + + return self.domain()(self._base_valuation.lift(num)) / self.domain()(self._base_valuation.lift(den)) + + def value_group(self): + r""" + Return the value group of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(x).value_group() + Additive Abelian Group generated by 1 + + """ + return self._base_valuation.value_group() + + def reduce(self, f): + r""" + Return the reduction of ``f`` in :meth:`residue_ring`. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) + sage: v.reduce(x) + u1 + + """ + f = self.domain().coerce(f) + + if self(f) > 0: + return self.residue_field().zero() + if self(f) < 0: + raise ValueError("cannot reduce element of negative valuation") + + base = self._base_valuation + + num = f.numerator() + den = f.denominator() + + assert base(num) == base(den) + shift = base.element_with_valuation(-base(num)) + num *= shift + den *= shift + ret = base.reduce(num) / base.reduce(den) + assert not ret.is_zero() + return self.residue_field()(ret) + + def _repr_(self): + r""" + Return a printable representation of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(x^2 + 1) # indirect doctest + (x^2 + 1)-adic valuation + + """ + from sage.rings.valuation.augmented_valuation import AugmentedValuation_base + from sage.rings.valuation.gauss_valuation import GaussValuation + if isinstance(self._base_valuation, AugmentedValuation_base): + if self._base_valuation._base_valuation == GaussValuation(self.domain()._ring, TrivialValuation(self.domain().constant_base_field())): + if self._base_valuation._mu == 1: + return "(%r)-adic valuation" % (self._base_valuation.phi()) + vK = self._base_valuation.restriction(self._base_valuation.domain().base_ring()) + if self._base_valuation == GaussValuation(self.domain()._ring, vK): + return repr(vK) + return "Valuation on rational function field induced by %s" % self._base_valuation + + def extensions(self, L): + r""" + Return all extensions of this valuation to ``L`` which has a larger + constant field than the domain of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x^2 + 1) + sage: L. = FunctionField(GaussianIntegers().fraction_field()) + sage: v.extensions(L) # indirect doctest + [(x - I)-adic valuation, (x + I)-adic valuation] + + """ + K = self.domain() + if L is K: + return [self] + + from sage.categories.function_fields import FunctionFields + if (L in FunctionFields() + and K.is_subring(L) + and L.base() is L + and L.constant_base_field() is not K.constant_base_field() + and K.constant_base_field().is_subring(L.constant_base_field())): + # The above condition checks whether L is an extension of K that + # comes from an extension of the field of constants + # Condition "L.base() is L" is important so we do not call this + # code for extensions from K(x) to K(x)(y) + + # We extend the underlying valuation on the polynomial ring + W = self._base_valuation.extensions(L._ring) + return [L.valuation(w) for w in W] + + return super().extensions(L) + + def _call_(self, f): + r""" + Evaluate this valuation at the function ``f``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x) # indirect doctest + sage: v((x+1)/x^2) + -2 + + """ + return self._base_valuation(f.numerator()) - self._base_valuation(f.denominator()) + + def residue_ring(self): + r""" + Return the residue field of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(x).residue_ring() + Rational Field + + """ + return self._base_valuation.residue_ring().fraction_field() + + def restriction(self, ring): + r""" + Return the restriction of this valuation to ``ring``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(x).restriction(QQ) + Trivial valuation on Rational Field + + """ + if ring.is_subring(self._base_valuation.domain()): + return self._base_valuation.restriction(ring) + return super().restriction(ring) + + def simplify(self, f, error=None, force=False): + r""" + Return a simplified version of ``f``. + + Produce an element which differs from ``f`` by an element of + valuation strictly greater than the valuation of ``f`` (or strictly + greater than ``error`` if set.) + + If ``force`` is not set, then expensive simplifications may be avoided. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(2) + sage: f = (x + 1)/(x - 1) + + As the coefficients of this fraction are small, we do not simplify as + this could be very costly in some cases:: + + sage: v.simplify(f) + (x + 1)/(x - 1) + + However, simplification can be forced:: + + sage: v.simplify(f, force=True) + 3 + + """ + f = self.domain().coerce(f) + + if error is None: + # if the caller was sure that we should simplify, then we should try to do the best simplification possible + error = self(f) if force else self.upper_bound(f) + + from sage.rings.infinity import infinity + if error is infinity: + return f + + numerator = f.numerator() + denominator = f.denominator() + + v_numerator = self._base_valuation(numerator) + v_denominator = self._base_valuation(denominator) + + if v_numerator - v_denominator > error: + return self.domain().zero() + + if error == -infinity: + # This case is not implemented yet, so we just return f which is always safe. + return f + + numerator = self.domain()(self._base_valuation.simplify(numerator, error=error+v_denominator, force=force)) + denominator = self.domain()(self._base_valuation.simplify(denominator, error=max(v_denominator, error - v_numerator + 2*v_denominator), force=force)) + + ret = numerator/denominator + assert self(ret - f) > error + return ret + + def _relative_size(self, f): + r""" + Return an estimate on the coefficient size of ``f``. + + The number returned is an estimate on the factor between the number of + bits used by ``f`` and the minimal number of bits used by an element + congruent to ``f``. + + This can be used by :meth:`simplify` to decide whether simplification + of coefficients is going to lead to a significant shrinking of the + coefficients of ``f``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(0) + sage: f = (x + 1024)/(x - 1024) + + Here we report a small size, as the numerator and the denominator + independently cannot be simplified much:: + + sage: v._relative_size(f) + 1 + + However, a forced simplification, finds that we could have saved many + more bits:: + + sage: v.simplify(f, force=True) + -1 + + """ + return max(self._base_valuation._relative_size(f.numerator()), self._base_valuation._relative_size(f.denominator())) + + +class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base, RationalFunctionFieldValuation_base): + r""" + Valuation of a finite place of a function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x + 1); v # indirect doctest + (x + 1)-adic valuation + + A finite place with residual degree:: + + sage: w = K.valuation(x^2 + 1); w + (x^2 + 1)-adic valuation + + A finite place with ramification:: + + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari + sage: L. = FunctionField(K) # optional - sage.libs.pari + sage: u = L.valuation(x^3 - t); u # optional - sage.libs.pari + (x^3 + 2*t)-adic valuation + + A finite place with residual degree and ramification:: + + sage: q = L.valuation(x^6 - t); q # optional - sage.libs.pari + (x^6 + 2*t)-adic valuation + + """ + def __init__(self, parent, base_valuation): + r""" + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(x + 1) + sage: from sage.rings.function_field.valuation import FiniteRationalFunctionFieldValuation + sage: isinstance(v, FiniteRationalFunctionFieldValuation) + True + + """ + InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) + ClassicalFunctionFieldValuation_base.__init__(self, parent) + RationalFunctionFieldValuation_base.__init__(self, parent) + + +class NonClassicalRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, RationalFunctionFieldValuation_base): + r""" + Valuation induced by a valuation on the underlying polynomial ring which is + non-classical. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = GaussValuation(QQ['x'], QQ.valuation(2)) + sage: w = K.valuation(v); w # indirect doctest + 2-adic valuation + + """ + def __init__(self, parent, base_valuation): + r""" + TESTS: + + There is some support for discrete pseudo-valuations on rational + function fields in the code. However, since these valuations must send + elements to `-\infty`, they are not supported yet:: + + sage: R. = QQ[] + sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity) + sage: K. = FunctionField(QQ) + sage: w = K.valuation(v) + sage: from sage.rings.function_field.valuation import NonClassicalRationalFunctionFieldValuation + sage: isinstance(w, NonClassicalRationalFunctionFieldValuation) + True + + """ + InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation) + RationalFunctionFieldValuation_base.__init__(self, parent) + + def residue_ring(self): + r""" + Return the residue field of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = valuations.GaussValuation(QQ['x'], QQ.valuation(2)) + sage: w = K.valuation(v) + sage: w.residue_ring() + Rational function field in x over Finite Field of size 2 + + sage: R. = QQ[] + sage: vv = v.augmentation(x, 1) + sage: w = K.valuation(vv) + sage: w.residue_ring() + Rational function field in x over Finite Field of size 2 + + sage: R. = K[] + sage: L. = K.extension(y^2 + 2*x) # optional - sage.libs.singular + sage: w.extension(L).residue_ring() # optional - sage.libs.singular + Function field in u2 defined by u2^2 + x + + TESTS: + + This still works for pseudo-valuations:: + + sage: R. = QQ[] + sage: v = valuations.GaussValuation(R, QQ.valuation(2)) + sage: vv = v.augmentation(x, infinity) + sage: K. = FunctionField(QQ) + sage: w = K.valuation(vv) + sage: w.residue_ring() + Finite Field of size 2 + + """ + if not self.is_discrete_valuation(): + # A pseudo valuation attaining negative infinity does typically not have a function field as its residue ring + return super().residue_ring() + return self._base_valuation.residue_ring().fraction_field().function_field() + + +class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, DiscreteFunctionFieldValuation_base): + r""" + A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is + another function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L); w # optional - sage.libs.singular + (x - 1)-adic valuation + + """ + def __init__(self, parent, approximant, G, approximants): + r""" + TESTS:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular + sage: from sage.rings.function_field.valuation import FunctionFieldFromLimitValuation + sage: isinstance(w, FunctionFieldFromLimitValuation) # optional - sage.libs.singular + True + + """ + FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants) + DiscreteFunctionFieldValuation_base.__init__(self, parent) + + def _to_base_domain(self, f): + r""" + Return ``f`` as an element of the domain of the underlying limit valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular + sage: w._to_base_domain(y).parent() # optional - sage.libs.singular + Univariate Polynomial Ring in y over Rational function field in x over Rational Field + + """ + return f.element() + + def scale(self, scalar): + r""" + Return this valuation scaled by ``scalar``. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.libs.singular + sage: 3*w # optional - sage.libs.singular + 3 * (x - 1)-adic valuation + + """ + if scalar in QQ and scalar > 0 and scalar != 1: + return self.domain().valuation(self._base_valuation._initial_approximation.scale(scalar)) + return super().scale(scalar) + + +class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValuation_base): + r""" + A valuation on a function field which relies on a ``base_valuation`` on an + isomorphic function field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x); v # optional - sage.libs.pari + Valuation at the infinite place + + """ + def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): + r""" + TESTS:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuation_base + sage: isinstance(v, FunctionFieldMappedValuation_base) # optional - sage.libs.pari + True + + """ + FunctionFieldValuation_base.__init__(self, parent) + MappedValuation_base.__init__(self, parent, base_valuation) + + self._to_base = to_base_valuation_domain + self._from_base = from_base_valuation_domain + + def _to_base_domain(self, f): + r""" + Return ``f`` as an element in the domain of ``_base_valuation``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w._to_base_domain(y) # optional - sage.libs.pari + x^2*y + + """ + return self._to_base(f) + + def _from_base_domain(self, f): + r""" + Return ``f`` as an element in the domain of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari + y + + r""" + return self._from_base(f) + + def scale(self, scalar): + r""" + Return this valuation scaled by ``scalar``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: 3*w # optional - sage.libs.pari + 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) + + """ + from sage.rings.rational_field import QQ + if scalar in QQ and scalar > 0 and scalar != 1: + return self.domain().valuation((self._base_valuation.scale(scalar), self._to_base, self._from_base)) + return super().scale(scalar) + + def _repr_(self): + r""" + Return a printable representation of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: v.extension(L) # indirect doctest # optional - sage.libs.pari + Valuation at the infinite place + + """ + to_base = repr(self._to_base) + if hasattr(self._to_base, '_repr_defn'): + to_base = self._to_base._repr_defn().replace('\n', ', ') + return "%r (in %r after %s)" % (self._base_valuation, self._base_valuation.domain(), to_base) + + def is_discrete_valuation(self): + r""" + Return whether this is a discrete valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - x^4 - 1) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w0,w1 = v.extensions(L) # optional - sage.libs.pari + sage: w0.is_discrete_valuation() # optional - sage.libs.pari + True + + """ + return self._base_valuation.is_discrete_valuation() + + +class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_base): + r""" + A valuation on a function field which relies on a ``base_valuation`` on an + isomorphic function field and which is such that the map from and to the + other function field is the identity on the constant field. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x); v # optional - sage.libs.pari + Valuation at the infinite place + + """ + def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain): + r""" + TESTS:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuationRelative_base + sage: isinstance(v, FunctionFieldMappedValuationRelative_base) # optional - sage.libs.pari + True + + """ + FunctionFieldMappedValuation_base.__init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain) + if self.domain().constant_base_field() is not base_valuation.domain().constant_base_field(): + raise ValueError("constant fields must be identical but they differ for %r and %r" % (self.domain(), base_valuation.domain())) + + def restriction(self, ring): + r""" + Return the restriction of this valuation to ``ring``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: K.valuation(1/x).restriction(GF(2)) # optional - sage.libs.pari + Trivial valuation on Finite Field of size 2 + + """ + if ring.is_subring(self.domain().constant_base_field()): + return self._base_valuation.restriction(ring) + return super().restriction(ring) + + +class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base): + r""" + Valuation on a rational function field that is implemented after a map to + an isomorphic rational function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) + sage: w = K.valuation(w) + sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v + Valuation on rational function field induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] (in Rational function field in x over Rational Field after x |--> 1/x) + + """ + def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain): + r""" + TESTS:: + + sage: K. = FunctionField(QQ) + sage: R. = QQ[] + sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) + sage: w = K.valuation(w) + sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) + sage: from sage.rings.function_field.valuation import RationalFunctionFieldMappedValuation + sage: isinstance(v, RationalFunctionFieldMappedValuation) + True + + """ + FunctionFieldMappedValuationRelative_base.__init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain) + RationalFunctionFieldValuation_base.__init__(self, parent) + + +class InfiniteRationalFunctionFieldValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base): + r""" + Valuation of the infinite place of a function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1/x) # indirect doctest + + """ + def __init__(self, parent): + r""" + TESTS:: + + sage: K. = FunctionField(QQ) + sage: v = K.valuation(1/x) # indirect doctest + sage: from sage.rings.function_field.valuation import InfiniteRationalFunctionFieldValuation + sage: isinstance(v, InfiniteRationalFunctionFieldValuation) + True + + """ + x = parent.domain().gen() + FunctionFieldMappedValuationRelative_base.__init__(self, parent, FunctionFieldValuation(parent.domain(), x), parent.domain().hom([1/x]), parent.domain().hom([1/x])) + RationalFunctionFieldValuation_base.__init__(self, parent) + ClassicalFunctionFieldValuation_base.__init__(self, parent) + + def _repr_(self): + r""" + Return a printable representation of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(QQ) + sage: K.valuation(1/x) # indirect doctest + Valuation at the infinite place + + """ + return "Valuation at the infinite place" + + +class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative_base): + r""" + A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is + another function field which redirects to another ``base_valuation`` on an + isomorphism function field `M=K[y]/(H)`. + + The isomorphisms must be trivial on ``K``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + + sage: w(x) # optional - sage.libs.pari + -1 + sage: w(y) # optional - sage.libs.pari + -3/2 + sage: w.uniformizer() # optional - sage.libs.pari + 1/x^2*y + + TESTS:: + + sage: from sage.rings.function_field.valuation import FunctionFieldExtensionMappedValuation + sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari + True + + """ + def _repr_(self): + r""" + Return a printable representation of this valuation. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L); w # optional - sage.libs.pari + Valuation at the infinite place + + sage: K. = FunctionField(QQ) + sage: R. = K[] + sage: L. = K.extension(y^2 - 1/x^2 - 1) # optional - sage.libs.singular + sage: v = K.valuation(1/x) # optional - sage.libs.singular + sage: w = v.extensions(L); w # optional - sage.libs.singular + [[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation, + [ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation] + + """ + assert(self.domain().base() is not self.domain()) + if repr(self._base_valuation) == repr(self.restriction(self.domain().base())): + return repr(self._base_valuation) + return super()._repr_() + + def restriction(self, ring): + r""" + Return the restriction of this valuation to ``ring``. + + EXAMPLES:: + + sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari + sage: R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari + sage: w.restriction(K) is v # optional - sage.libs.pari + True + """ + if ring.is_subring(self.domain().base()): + return self._base_valuation.restriction(ring) + return super().restriction(ring) From 4c7515e528e0a157bfe2e617ab702438d82e5831 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 15 Mar 2023 14:47:49 +0900 Subject: [PATCH 26/54] Small fix --- src/sage/rings/function_field/function_field_polymod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index a2cb0368f4a..c440c893ebd 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -124,8 +124,8 @@ def __init__(self, polynomial, names, category=None): TypeError: unable to evaluate 'x' in Fraction Field of Univariate Polynomial Ring in t over Rational Field """ - from sage.rings.polynomial.polynomial_element import is_Polynomial - if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial): + from sage.rings.polynomial.polynomial_element import Polynomial + if polynomial.parent().ngens() > 1 or not isinstance(polynomial, Polynomial): raise TypeError("polynomial must be univariate a polynomial") if names is None: names = (polynomial.variable_name(), ) From 4aa6c00893ccfe68d3ee8c69650fa16fda7dd20e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 15 Mar 2023 19:34:34 -0700 Subject: [PATCH 27/54] src/sage/rings/function_field: Make 'tox -e pycodestyle-minimal' pass --- src/sage/rings/function_field/derivations.py | 2 -- src/sage/rings/function_field/derivations_polymod.py | 1 - src/sage/rings/function_field/derivations_rational.py | 2 -- src/sage/rings/function_field/function_field_polymod.py | 1 - src/sage/rings/function_field/ideal_polymod.py | 2 -- src/sage/rings/function_field/ideal_rational.py | 2 -- src/sage/rings/function_field/order_polymod.py | 1 - src/sage/rings/function_field/place_polymod.py | 2 -- src/sage/rings/function_field/place_rational.py | 2 -- 9 files changed, 15 deletions(-) diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index 4a088e781fb..6ee7e731713 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -84,5 +84,3 @@ def _rmul_(self, factor): x*d/dx """ return self._lmul_(factor) - - diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 6d59aef7158..d00ed282403 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -889,4 +889,3 @@ def _derive(self, f, i, separating_element=None): cache[f, i] = der return der - diff --git a/src/sage/rings/function_field/derivations_rational.py b/src/sage/rings/function_field/derivations_rational.py index a7c72853661..73760bebf3c 100644 --- a/src/sage/rings/function_field/derivations_rational.py +++ b/src/sage/rings/function_field/derivations_rational.py @@ -109,5 +109,3 @@ def _lmul_(self, factor): x*d/dx """ return type(self)(self.parent(), [factor * self._u]) - - diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index c440c893ebd..04e70275118 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -2532,4 +2532,3 @@ class FunctionField_global_integral(FunctionField_global, FunctionField_integral finite constant field. """ pass - diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index c89722ebf20..47fdf7b66b5 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -1689,5 +1689,3 @@ def _factor(self): prime = FunctionFieldIdealInfinite_polymod(O, iprime) factors.append((prime, exp)) return factors - - diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 9bad335cc02..72decf69121 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -601,5 +601,3 @@ def _factor(self): return [] else: return [(self.ring().ideal(g), m)] - - diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 9e2e0124d68..ff5a7ae82a2 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -1431,4 +1431,3 @@ def split(h): decomposition.append((prime, degree, index)) return decomposition - diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index 06129286b1e..c7781a975f9 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -659,5 +659,3 @@ def valuation_ring(self): from .valuation_ring import FunctionFieldValuationRing return FunctionFieldValuationRing(self.function_field(), self) - - diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py index 74255ab086c..760c44d846e 100644 --- a/src/sage/rings/function_field/place_rational.py +++ b/src/sage/rings/function_field/place_rational.py @@ -171,5 +171,3 @@ def valuation_ring(self): from .valuation_ring import FunctionFieldValuationRing return FunctionFieldValuationRing(self.function_field(), self) - - From f3f8269856c5393c2e0418f32eb65cdf3ed9c81e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 15 Mar 2023 20:53:21 -0700 Subject: [PATCH 28/54] sage.features: Add feature sage.rings.function_field --- src/sage/features/sagemath.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index c8824682d60..d98ea45d589 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -14,6 +14,7 @@ from . import PythonModule, StaticFile from .join_feature import JoinFeature +from .singular import sage__libs__singular class sagemath_doc_html(StaticFile): @@ -155,6 +156,29 @@ def __init__(self): [PythonModule('sage.plot.plot')]) +class sage__rings__function_field(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.function_field`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__rings__function_field + sage: sage__rings__function_field().is_present() # optional - sage.rings.function_field + FeatureTestResult('sage.rings.function_field', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__rings__function_field + sage: isinstance(sage__rings__function_field(), sage__rings__function_field) + True + """ + JoinFeature.__init__(self, 'sage.rings.function_field', + [PythonModule('sage.rings.function_field.function_field_polymod'), + sage__libs__singular()]) + + class sage__rings__number_field(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.number_field`. @@ -271,6 +295,7 @@ def all_features(): sage__graphs(), sage__groups(), sage__plot(), + sage__rings__function_field(), sage__rings__number_field(), sage__rings__padics(), sage__rings__real_double(), From 8131fc619decf08d6e5f36bc6c6068ec467e89ba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 15 Mar 2023 21:11:42 -0700 Subject: [PATCH 29/54] src/sage/rings/function_field: Update doctests to use # optional - sage.rings.function_field --- src/sage/rings/function_field/constructor.py | 28 +- src/sage/rings/function_field/derivations.py | 6 +- .../function_field/derivations_polymod.py | 36 +-- src/sage/rings/function_field/differential.py | 289 +++++++++--------- 4 files changed, 180 insertions(+), 179 deletions(-) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index 457530a5dd0..5625934dd84 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -57,7 +57,7 @@ class FunctionFieldFactory(UniqueFactory): sage: L. = FunctionField(GF(7)); L # optional - sage.libs.pari Rational function field in y over Finite Field of size 7 sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^7 - z - y); M # optional - sage.libs.pari + sage: M. = L.extension(z^7 - z - y); M # optional - sage.libs.pari sage.rings.function_field Function field in z defined by z^7 + 6*z + 6*y TESTS:: @@ -133,9 +133,9 @@ class FunctionFieldExtensionFactory(UniqueFactory): sage: y2 = y*1 sage: y2 is y False - sage: L. = K.extension(x - y^2) # optional - sage.libs.singular - sage: M. = K.extension(x - y2^2) # optional - sage.libs.singular - sage: L is M # optional - sage.libs.singular + sage: L. = K.extension(x - y^2) # optional - sage.rings.function_field + sage: M. = K.extension(x - y2^2) # optional - sage.rings.function_field + sage: L is M # optional - sage.rings.function_field True """ def create_key(self,polynomial,names): @@ -147,7 +147,7 @@ def create_key(self,polynomial,names): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.rings.function_field TESTS: @@ -155,12 +155,12 @@ def create_key(self,polynomial,names): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z - 1) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z - 1) # optional - sage.rings.function_field sage: R. = K[] - sage: N. = K.extension(z - 1) # optional - sage.libs.singular - sage: M is N # optional - sage.libs.singular + sage: N. = K.extension(z - 1) # optional - sage.rings.function_field + sage: M is N # optional - sage.rings.function_field False """ @@ -179,10 +179,10 @@ def create_object(self,version,key,**extra_args): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.libs.singular - sage: y2 = y*1 # optional - sage.libs.singular - sage: M. = K.extension(x - y2^2) # indirect doctest # optional - sage.libs.singular - sage: L is M # optional - sage.libs.singular + sage: L. = K.extension(x - y^2) # indirect doctest # optional - sage.rings.function_field + sage: y2 = y*1 # optional - sage.rings.function_field + sage: M. = K.extension(x - y2^2) # indirect doctest # optional - sage.rings.function_field + sage: L is M # optional - sage.rings.function_field True """ from . import function_field_polymod, function_field_rational diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index 6ee7e731713..89452dcc628 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -5,9 +5,9 @@ derivation is available:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h(y^2, 2) # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: h = L.higher_derivation() # optional - sage.libs.pari sage.rings.function_field + sage: h(y^2, 2) # optional - sage.libs.pari sage.rings.function_field ((x^7 + 1)/x^2)*y^2 + x^3*y AUTHORS: diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index d00ed282403..5348a8669a7 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -553,11 +553,11 @@ class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari sage.modules + sage: h # optional - sage.libs.pari Higher derivation map: From: Function field in y defined by y^3 + x^3*y + x To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) # optional - sage.libs.pari sage.modules + sage: h(y^2, 2) # optional - sage.libs.pari ((x^7 + 1)/x^2)*y^2 + x^3*y """ @@ -569,8 +569,8 @@ def __init__(self, field): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari """ from sage.matrix.constructor import matrix @@ -597,8 +597,8 @@ def _call_with_args(self, f, args, kwds): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari ((x^7 + 1)/x^2)*y^2 + x^3*y """ return self._derive(f, *args, **kwds) @@ -614,18 +614,18 @@ def _derive(self, f, i, separating_element=None): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: y^3 # optional - sage.libs.pari sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: y^3 # optional - sage.libs.pari x^3*y + x - sage: h._derive(y^3,0) # optional - sage.libs.pari sage.modules + sage: h._derive(y^3,0) # optional - sage.libs.pari x^3*y + x - sage: h._derive(y^3,1) # optional - sage.libs.pari sage.modules + sage: h._derive(y^3,1) # optional - sage.libs.pari x^4*y^2 + 1 - sage: h._derive(y^3,2) # optional - sage.libs.pari sage.modules + sage: h._derive(y^3,2) # optional - sage.libs.pari x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) # optional - sage.libs.pari sage.modules + sage: h._derive(y^3,3) # optional - sage.libs.pari (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) # optional - sage.libs.pari sage.modules + sage: h._derive(y^3,4) # optional - sage.libs.pari (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y """ F = self._field @@ -713,9 +713,9 @@ def _prime_power_representation(self, f, separating_element=None): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: b = h._prime_power_representation(y) # optional - sage.libs.pari sage.modules - sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: b = h._prime_power_representation(y) # optional - sage.libs.pari + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari True """ F = self._field @@ -759,8 +759,8 @@ def _pth_root(self, c): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.modules - sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari sage.modules + sage: h = L.higher_derivation() # optional - sage.libs.pari + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari y^2 + x^2 """ from sage.modules.free_module_element import vector diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index 29ff02cd71a..4ad17fd18e1 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Differentials of function fields @@ -9,34 +10,34 @@ the function field:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: f = x + y # optional - sage.libs.pari - sage: g = 1 / y # optional - sage.libs.pari - sage: df = f.differential() # optional - sage.libs.pari - sage: dg = g.differential() # optional - sage.libs.pari - sage: dfdg = f.derivative() / g.derivative() # optional - sage.libs.pari - sage: df == dfdg * dg # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: f = x + y # optional - sage.libs.pari sage.rings.function_field + sage: g = 1 / y # optional - sage.libs.pari sage.rings.function_field + sage: df = f.differential() # optional - sage.libs.pari sage.rings.function_field + sage: dg = g.differential() # optional - sage.libs.pari sage.rings.function_field + sage: dfdg = f.derivative() / g.derivative() # optional - sage.libs.pari sage.rings.function_field + sage: df == dfdg * dg # optional - sage.libs.pari sage.rings.function_field True - sage: df # optional - sage.libs.pari + sage: df # optional - sage.libs.pari sage.rings.function_field (x*y^2 + 1/x*y + 1) d(x) - sage: df.parent() # optional - sage.libs.pari + sage: df.parent() # optional - sage.libs.pari sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x We can compute a canonical divisor:: - sage: k = df.divisor() # optional - sage.libs.pari - sage: k.degree() # optional - sage.libs.pari + sage: k = df.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: k.degree() # optional - sage.libs.pari sage.rings.function_field 4 - sage: k.degree() == 2 * L.genus() - 2 # optional - sage.libs.pari + sage: k.degree() == 2 * L.genus() - 2 # optional - sage.libs.pari sage.rings.function_field True Exact differentials vanish and logarithmic differentials are stable under the Cartier operation:: - sage: df.cartier() # optional - sage.libs.pari + sage: df.cartier() # optional - sage.libs.pari sage.rings.function_field 0 - sage: w = 1/f * df # optional - sage.libs.pari - sage: w.cartier() == w # optional - sage.libs.pari + sage: w = 1/f * df # optional - sage.libs.pari sage.rings.function_field + sage: w.cartier() == w # optional - sage.libs.pari sage.rings.function_field True AUTHORS: @@ -78,7 +79,7 @@ class FunctionFieldDifferential(ModuleElement): EXAMPLES:: - sage: F.=FunctionField(QQ) + sage: F. = FunctionField(QQ) sage: f = x/(x^2 + x + 1) sage: f.differential() ((-x^2 + 1)/(x^4 + 2*x^3 + 3*x^2 + 2*x + 1)) d(x) @@ -86,10 +87,10 @@ class FunctionFieldDifferential(ModuleElement): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + x + x^3*Y) - sage: L(x).differential() + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.function_field + sage: L(x).differential() # optional - sage.rings.function_field d(x) - sage: y.differential() + sage: y.differential() # optional - sage.rings.function_field ((21/4*x/(x^7 + 27/4))*y^2 + ((3/2*x^7 + 9/4)/(x^8 + 27/4*x))*y + 7/2*x^4/(x^7 + 27/4)) d(x) """ def __init__(self, parent, f, t=None): @@ -117,11 +118,11 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari - sage: y.differential() # optional - sage.libs.pari + sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: y.differential() # optional - sage.libs.pari sage.rings.function_field (x*y^2 + 1/x*y) d(x) - sage: F.=FunctionField(QQ) + sage: F. = FunctionField(QQ) sage: f = 1/x sage: f.differential() (-1/x^2) d(x) @@ -143,7 +144,7 @@ def _latex_(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage: w = y.differential() # optional - sage.libs.pari sage: latex(w) # optional - sage.libs.pari \left( x y^{2} + \frac{1}{x} y \right)\, dx @@ -165,10 +166,10 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: {x.differential(): 1} # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: {x.differential(): 1} # optional - sage.libs.pari sage.rings.function_field {d(x): 1} - sage: {y.differential(): 1} # optional - sage.libs.pari + sage: {y.differential(): 1} # optional - sage.libs.pari sage.rings.function_field {(x*y^2 + 1/x*y) d(x): 1} """ return hash((self.parent(), self._f)) @@ -187,18 +188,18 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w1 = y.differential() # optional - sage.libs.pari - sage: w2 = L(x).differential() # optional - sage.libs.pari - sage: w3 = (x*y).differential() # optional - sage.libs.pari - sage: w1 < w2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w2 = L(x).differential() # optional - sage.libs.pari sage.rings.function_field + sage: w3 = (x*y).differential() # optional - sage.libs.pari sage.rings.function_field + sage: w1 < w2 # optional - sage.libs.pari sage.rings.function_field False - sage: w2 < w1 # optional - sage.libs.pari + sage: w2 < w1 # optional - sage.libs.pari sage.rings.function_field True - sage: w3 == x * w1 + y * w2 # optional - sage.libs.pari + sage: w3 == x * w1 + y * w2 # optional - sage.libs.pari sage.rings.function_field True - sage: F.=FunctionField(QQ) + sage: F. = FunctionField(QQ) sage: w1 = ((x^2+x+1)^10).differential() sage: w2 = (x^2+x+1).differential() sage: w1 < w2 @@ -221,10 +222,10 @@ def _add_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w1 = y.differential() # optional - sage.libs.pari - sage: w2 = (1/y).differential() # optional - sage.libs.pari - sage: w1 + w2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w2 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field + sage: w1 + w2 # optional - sage.libs.pari sage.rings.function_field (((x^3 + 1)/x^2)*y^2 + 1/x*y) d(x) sage: F. = FunctionField(QQ) @@ -249,10 +250,10 @@ def _div_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w1 = y.differential() # optional - sage.libs.pari - sage: w2 = (1/y).differential() # optional - sage.libs.pari - sage: w1 / w2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w2 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field + sage: w1 / w2 # optional - sage.libs.pari sage.rings.function_field y^2 sage: F. = FunctionField(QQ) @@ -273,10 +274,10 @@ def _neg_(self): EXAMPLES:: sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w1 = y.differential() # optional - sage.libs.pari - sage: w2 = (-y).differential() # optional - sage.libs.pari - sage: -w1 == w2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w2 = (-y).differential() # optional - sage.libs.pari sage.rings.function_field + sage: -w1 == w2 # optional - sage.libs.pari sage.rings.function_field True sage: F. = FunctionField(QQ) @@ -300,13 +301,13 @@ def _rmul_(self, f): EXAMPLES:: sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w1 = (1/y).differential() # optional - sage.libs.pari - sage: w2 = (-1/y^2) * y.differential() # optional - sage.libs.pari - sage: w1 == w2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w1 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field + sage: w2 = (-1/y^2) * y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w1 == w2 # optional - sage.libs.pari sage.rings.function_field True - sage: F.=FunctionField(QQ) + sage: F. = FunctionField(QQ) sage: w1 = (x^2*(x^2+x+1)).differential() sage: w2 = (x^2).differential() sage: w3 = (x^2+x+1).differential() @@ -329,25 +330,25 @@ def _acted_upon_(self, f, self_on_left): EXAMPLES:: sage: K. = FunctionField(GF(31)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x); _. = L[] # optional - sage.libs.pari - sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari - sage: z.differential() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x); _. = L[] # optional - sage.libs.pari sage.rings.function_field + sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari sage.rings.function_field + sage: z.differential() # optional - sage.libs.pari sage.rings.function_field (8/x*z) d(x) - sage: 1/(2*z) * y.differential() # optional - sage.libs.pari + sage: 1/(2*z) * y.differential() # optional - sage.libs.pari sage.rings.function_field (8/x*z) d(x) - sage: z * x.differential() # optional - sage.libs.pari + sage: z * x.differential() # optional - sage.libs.pari sage.rings.function_field (z) d(x) - sage: z * (y^2).differential() # optional - sage.libs.pari + sage: z * (y^2).differential() # optional - sage.libs.pari sage.rings.function_field (z) d(x) - sage: z * (z^4).differential() # optional - sage.libs.pari + sage: z * (z^4).differential() # optional - sage.libs.pari sage.rings.function_field (z) d(x) :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: y * x.differential() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: y * x.differential() # optional - sage.libs.pari sage.rings.function_field (y) d(x) """ F = f.parent() @@ -364,9 +365,9 @@ def divisor(self): EXAMPLES:: sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w = (1/y) * y.differential() # optional - sage.libs.pari - sage: w.divisor() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w = (1/y) * y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w.divisor() # optional - sage.libs.pari sage.rings.function_field - Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) - Place (x, y) @@ -395,9 +396,9 @@ def valuation(self, place): EXAMPLES:: sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w = (1/y) * y.differential() # optional - sage.libs.pari - sage: [w.valuation(p) for p in L.places()] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w = (1/y) * y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: [w.valuation(p) for p in L.places()] # optional - sage.libs.pari sage.rings.function_field [-1, -1, -1, 0, 1, 0] """ F = self.parent().function_field() @@ -434,26 +435,26 @@ def residue(self, place): and in an extension field:: sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: f = 0 # optional - sage.libs.pari - sage: while f == 0: # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: f = 0 # optional - sage.libs.pari sage.rings.function_field + sage: while f == 0: # optional - sage.libs.pari sage.rings.function_field ....: f = L.random_element() - sage: w = 1/f * f.differential() # optional - sage.libs.pari - sage: d = f.divisor() # optional - sage.libs.pari - sage: s = d.support() # optional - sage.libs.pari - sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari + sage: w = 1/f * f.differential() # optional - sage.libs.pari sage.rings.function_field + sage: d = f.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: s = d.support() # optional - sage.libs.pari sage.rings.function_field + sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari sage.rings.function_field 0 and also in a function field of characteristic zero:: sage: R. = FunctionField(QQ) sage: L. = R[] - sage: F. = R.extension(Y^2 - x^4 - 4*x^3 - 2*x^2 - 1) - sage: a = 6*x^2 + 5*x + 7 - sage: b = 2*x^6 + 8*x^5 + 3*x^4 - 4*x^3 -1 - sage: w = y*a/b*x.differential() - sage: d = w.divisor() - sage: sum([QQ(w.residue(p)) for p in d.support()]) + sage: F. = R.extension(Y^2 - x^4 - 4*x^3 - 2*x^2 - 1) # optional - sage.rings.function_field + sage: a = 6*x^2 + 5*x + 7 # optional - sage.rings.function_field + sage: b = 2*x^6 + 8*x^5 + 3*x^4 - 4*x^3 - 1 # optional - sage.rings.function_field + sage: w = y*a/b*x.differential() # optional - sage.rings.function_field + sage: d = w.divisor() # optional - sage.rings.function_field + sage: sum([QQ(w.residue(p)) for p in d.support()]) # optional - sage.rings.function_field 0 """ @@ -482,11 +483,11 @@ def monomial_coefficients(self, copy=True): EXAMPLES:: sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: d = y.differential() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: d = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: d # optional - sage.libs.pari sage.rings.function_field ((4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)) d(x) - sage: d.monomial_coefficients() # optional - sage.libs.pari + sage: d.monomial_coefficients() # optional - sage.libs.pari sage.rings.function_field {0: (4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)} """ return {0: self._f} @@ -506,8 +507,8 @@ class FunctionFieldDifferential_global(FunctionFieldDifferential): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: y.differential() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: y.differential() # optional - sage.libs.pari sage.rings.function_field (x*y^2 + 1/x*y) d(x) """ def cartier(self): @@ -528,10 +529,10 @@ def cartier(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: f = x/y # optional - sage.libs.pari - sage: w = 1/f*f.differential() # optional - sage.libs.pari - sage: w.cartier() == w # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: f = x/y # optional - sage.libs.pari sage.rings.function_field + sage: w = 1/f*f.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w.cartier() == w # optional - sage.libs.pari sage.rings.function_field True :: @@ -560,8 +561,8 @@ class DifferentialsSpace(UniqueRepresentation, Parent): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: L.space_of_differentials() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x The space of differentials is a one-dimensional module over the function @@ -573,12 +574,12 @@ class DifferentialsSpace(UniqueRepresentation, Parent): sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - 1/x) # optional - sage.libs.pari - sage: L(x).differential() # optional - sage.libs.pari + sage: L. = K.extension(y^5 - 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: L(x).differential() # optional - sage.libs.pari sage.rings.function_field 0 - sage: y.differential() # optional - sage.libs.pari + sage: y.differential() # optional - sage.libs.pari sage.rings.function_field d(y) - sage: (y^2).differential() # optional - sage.libs.pari + sage: (y^2).differential() # optional - sage.libs.pari sage.rings.function_field (2*y) d(y) """ Element = FunctionFieldDifferential @@ -590,9 +591,9 @@ def __init__(self, field, category=None): TESTS:: sage: K. = FunctionField(GF(4)); _.=K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: W = L.space_of_differentials() # optional - sage.libs.pari - sage: TestSuite(W).run() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: W = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(W).run() # optional - sage.libs.pari sage.rings.function_field """ Parent.__init__(self, base=field, category=Modules(field).FiniteDimensional().WithBasis().or_subcategory(category)) @@ -616,9 +617,9 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w = y.differential() # optional - sage.libs.pari - sage: w.parent() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: w = y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: w.parent() # optional - sage.libs.pari sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x """ return "Space of differentials of {}".format(self.base()) @@ -634,13 +635,13 @@ def _element_constructor_(self, f): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: S = L.space_of_differentials() # optional - sage.libs.pari - sage: S(y) # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: S(y) # optional - sage.libs.pari sage.rings.function_field (x*y^2 + 1/x*y) d(x) - sage: S(y) in S # optional - sage.libs.pari + sage: S(y) in S # optional - sage.libs.pari sage.rings.function_field True - sage: S(1) # optional - sage.libs.pari + sage: S(1) # optional - sage.libs.pari sage.rings.function_field 0 """ if f in self.base(): @@ -658,8 +659,8 @@ def _coerce_map_from_(self, S): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: L.space_of_differentials().coerce_map_from(K.space_of_differentials()) + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: L.space_of_differentials().coerce_map_from(K.space_of_differentials()) # optional - sage.rings.function_field Inclusion morphism: From: Space of differentials of Rational function field in x over Rational Field To: Space of differentials of Function field in y defined by y^2 - x*y + 4*x^3 @@ -676,9 +677,9 @@ def function_field(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: S = L.space_of_differentials() # optional - sage.libs.pari - sage: S.function_field() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: S.function_field() # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^3 + x^3*y + x """ return self.base() @@ -690,9 +691,9 @@ def _an_element_(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: S = L.space_of_differentials() # optional - sage.libs.pari - sage: S.an_element() # random # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: S.an_element() # random # optional - sage.libs.pari sage.rings.function_field (x*y^2 + 1/x*y) d(x) """ F = self.base() @@ -705,9 +706,9 @@ def basis(self): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: S = L.space_of_differentials() # optional - sage.libs.pari - sage: S.basis() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: S.basis() # optional - sage.libs.pari sage.rings.function_field Family (d(x),) """ return Family([self.element_class(self, self.base().one())]) @@ -724,8 +725,8 @@ class DifferentialsSpace_global(DifferentialsSpace): EXAMPLES:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: L.space_of_differentials() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldDifferential_global @@ -738,10 +739,10 @@ class DifferentialsSpaceInclusion(Morphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: OK = K.space_of_differentials() - sage: OL = L.space_of_differentials() - sage: OL.coerce_map_from(OK) + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: OK = K.space_of_differentials() # optional - sage.rings.function_field + sage: OL = L.space_of_differentials() # optional - sage.rings.function_field + sage: OL.coerce_map_from(OK) # optional - sage.rings.function_field Inclusion morphism: From: Space of differentials of Rational function field in x over Rational Field To: Space of differentials of Function field in y defined by y^2 - x*y + 4*x^3 @@ -754,10 +755,10 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: OK = K.space_of_differentials() - sage: OL = L.space_of_differentials() - sage: OL.coerce_map_from(OK) + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: OK = K.space_of_differentials() # optional - sage.rings.function_field + sage: OL = L.space_of_differentials() # optional - sage.rings.function_field + sage: OL.coerce_map_from(OK) # optional - sage.rings.function_field Inclusion morphism: From: Space of differentials of Rational function field in x over Rational Field To: Space of differentials of Function field in y defined by y^2 - x*y + 4*x^3 @@ -774,10 +775,10 @@ def is_injective(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: OK = K.space_of_differentials() - sage: OL = L.space_of_differentials() - sage: OL.coerce_map_from(OK).is_injective() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: OK = K.space_of_differentials() # optional - sage.rings.function_field + sage: OL = L.space_of_differentials() # optional - sage.rings.function_field + sage: OL.coerce_map_from(OK).is_injective() # optional - sage.rings.function_field True """ return True @@ -789,15 +790,15 @@ def is_surjective(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) - sage: OK = K.space_of_differentials() - sage: OL = L.space_of_differentials() - sage: OL.coerce_map_from(OK).is_surjective() + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: OK = K.space_of_differentials() # optional - sage.rings.function_field + sage: OL = L.space_of_differentials() # optional - sage.rings.function_field + sage: OL.coerce_map_from(OK).is_surjective() # optional - sage.rings.function_field False - sage: S. = L[] - sage: M. = L.extension(z - 1) - sage: OM = M.space_of_differentials() - sage: OM.coerce_map_from(OL).is_surjective() + sage: S. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z - 1) # optional - sage.rings.function_field + sage: OM = M.space_of_differentials() # optional - sage.rings.function_field + sage: OM.coerce_map_from(OL).is_surjective() # optional - sage.rings.function_field True """ K = self.domain().function_field() @@ -815,11 +816,11 @@ def _call_(self, v): EXAMPLES:: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^2 - x*Y + 4*x^3) # optional - sage.rings.number_field - sage: OK = K.space_of_differentials() # optional - sage.rings.number_field - sage: OL = L.space_of_differentials() # optional - sage.rings.number_field - sage: mor = OL.coerce_map_from(OK) # optional - sage.rings.number_field - sage: mor(x.differential()).parent() # optional - sage.rings.number_field + sage: L. = K.extension(Y^2 - x*Y + 4*x^3) # optional - sage.rings.function_field sage.rings.number_field + sage: OK = K.space_of_differentials() # optional - sage.rings.function_field sage.rings.number_field + sage: OL = L.space_of_differentials() # optional - sage.rings.function_field sage.rings.number_field + sage: mor = OL.coerce_map_from(OK) # optional - sage.rings.function_field sage.rings.number_field + sage: mor(x.differential()).parent() # optional - sage.rings.function_field sage.rings.number_field Space of differentials of Function field in y defined by y^2 - x*y + 4*x^3 """ domain = self.domain() From 14bf26fe4fe39bcda68f5b029b4ae6e8c6f16c37 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 2 Mar 2023 16:43:30 -0800 Subject: [PATCH 30/54] sage.features: Add features sage.libs.pari, sage.modules --- src/sage/features/sagemath.py | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index d98ea45d589..765142fa2c7 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -134,6 +134,50 @@ def __init__(self): [PythonModule('sage.groups.perm_gps.permgroup')]) +class sage__libs__pari(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.pari`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__pari + sage: sage__libs__pari().is_present() # optional - sage.libs.pari + FeatureTestResult('sage.libs.pari', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__pari + sage: isinstance(sage__libs__pari(), sage__libs__pari) + True + """ + JoinFeature.__init__(self, 'sage.libs.pari', + [PythonModule('sage.libs.pari.convert_sage')]) + + +class sage__modules(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of :mod:`sage.modules`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__modules + sage: sage__modules().is_present() # optional - sage.modules + FeatureTestResult('sage.modules', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__modules + sage: isinstance(sage__modules(), sage__modules) + True + """ + JoinFeature.__init__(self, 'sage.modules', + [PythonModule('sage.modules.free_module')]) + + class sage__plot(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.plot`. @@ -294,6 +338,8 @@ def all_features(): sage__geometry__polyhedron(), sage__graphs(), sage__groups(), + sage__libs__pari(), + sage__modules(), sage__plot(), sage__rings__function_field(), sage__rings__number_field(), From fde26d60b1fb23ea624749ba95e2a872c388e94b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 15 Mar 2023 23:17:16 -0700 Subject: [PATCH 31/54] src/sage/rings/function_field: Update remaining doctests to use # optional - sage.rings.function_field --- src/sage/rings/function_field/divisor.py | 3 +- src/sage/rings/function_field/element.pyx | 154 +++---- .../rings/function_field/element_polymod.pyx | 75 ++-- .../rings/function_field/element_rational.pyx | 4 +- src/sage/rings/function_field/extensions.py | 66 +-- .../rings/function_field/function_field.py | 320 +++++++------- .../function_field/function_field_polymod.py | 350 +++++++-------- .../function_field/function_field_rational.py | 30 +- src/sage/rings/function_field/ideal.py | 404 +++++++++--------- .../rings/function_field/ideal_polymod.py | 206 ++++----- .../rings/function_field/ideal_rational.py | 36 +- src/sage/rings/function_field/maps.py | 243 ++++++----- src/sage/rings/function_field/order.py | 34 +- src/sage/rings/function_field/order_basis.py | 134 +++--- .../rings/function_field/order_polymod.py | 390 ++++++++--------- .../rings/function_field/order_rational.py | 18 +- src/sage/rings/function_field/place.py | 124 +++--- .../rings/function_field/place_polymod.py | 19 +- .../rings/function_field/place_rational.py | 61 +-- src/sage/rings/function_field/valuation.py | 183 ++++---- .../rings/function_field/valuation_ring.py | 1 + 21 files changed, 1435 insertions(+), 1420 deletions(-) diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 5b41e7ee4b6..054e1044e8a 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -1,4 +1,5 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) +# sage.doctest: optional - sage.rings.function_field (because almost all doctests use function field extensions) """ Divisors of function fields diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index cd06093ba84..e19c07ee36a 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -21,15 +21,15 @@ Arithmetic with rational functions:: Derivatives of elements in separable extensions:: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).derivative() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.rings.function_field ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 The divisor of an element of a global function field:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: y.divisor() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: y.divisor() # optional - sage.libs.pari sage.rings.function_field - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -135,8 +135,8 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(b^2 - a) # optional - sage.libs.singular - sage: b.__pari__() # optional - sage.libs.singular + sage: L. = K.extension(b^2 - a) # optional - sage.rings.function_field + sage: b.__pari__() # optional - sage.rings.function_field Traceback (most recent call last): ... NotImplementedError: PARI does not support general function field elements. @@ -182,11 +182,11 @@ cdef class FunctionFieldElement(FieldElement): Now an example in a nontrivial extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.matrix() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: y.matrix() # optional - sage.modules sage.rings.function_field [ 0 1] [-4*x^3 x] - sage: y.matrix().charpoly('Z') # optional - sage.libs.singular sage.modules + sage: y.matrix().charpoly('Z') # optional - sage.modules sage.rings.function_field Z^2 - x*Z + 4*x^3 An example in a relative extension, where neither function @@ -194,21 +194,21 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: M. = L[] # optional - sage.libs.singular - sage: Z. = L.extension(T^3 - y^2*T + x) # optional - sage.libs.singular - sage: alpha.matrix() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: M. = L[] # optional - sage.rings.function_field + sage: Z. = L.extension(T^3 - y^2*T + x) # optional - sage.rings.function_field + sage: alpha.matrix() # optional - sage.modules sage.rings.function_field [ 0 1 0] [ 0 0 1] [ -x x*y - 4*x^3 0] - sage: alpha.matrix(K) # optional - sage.libs.singular sage.modules + sage: alpha.matrix(K) # optional - sage.modules sage.rings.function_field [ 0 0 1 0 0 0] [ 0 0 0 1 0 0] [ 0 0 0 0 1 0] [ 0 0 0 0 0 1] [ -x 0 -4*x^3 x 0 0] [ 0 -x -4*x^4 -4*x^3 + x^2 0 0] - sage: alpha.matrix(Z) # optional - sage.libs.singular sage.modules + sage: alpha.matrix(Z) # optional - sage.modules sage.rings.function_field [alpha] We show that this matrix does indeed work as expected when making a @@ -216,13 +216,13 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: V, from_V, to_V = L.vector_space() # optional - sage.libs.singular sage.modules - sage: y5 = to_V(y^5); y5 # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.rings.function_field + sage: V, from_V, to_V = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: y5 = to_V(y^5); y5 # optional - sage.modules sage.rings.function_field ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y4y = to_V(y^4) * y.matrix(); y4y # optional - sage.libs.singular sage.modules + sage: y4y = to_V(y^4) * y.matrix(); y4y # optional - sage.modules sage.rings.function_field ((x^4 + 1)/x, 2*x, 0, 0, 0) - sage: y5 == y4y # optional - sage.libs.singular sage.modules + sage: y5 == y4y # optional - sage.modules sage.rings.function_field True """ # multiply each element of the vector space isomorphic to the parent @@ -244,8 +244,8 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.trace() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: y.trace() # optional - sage.modules sage.rings.function_field x """ return self.matrix().trace() @@ -257,18 +257,18 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.norm() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: y.norm() # optional - sage.modules sage.rings.function_field 4*x^3 The norm is relative:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: z.norm() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.rings.function_field + sage: z.norm() # optional - sage.modules sage.rings.function_field -x - sage: z.norm().parent() # optional - sage.libs.singular sage.modules + sage: z.norm().parent() # optional - sage.modules sage.rings.function_field Function field in y defined by y^2 - x*y + 4*x^3 """ return self.matrix().determinant() @@ -317,13 +317,13 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: x.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.rings.function_field + sage: x.characteristic_polynomial('W') # optional - sage.modules sage.rings.function_field W - x - sage: y.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules + sage: y.characteristic_polynomial('W') # optional - sage.modules sage.rings.function_field W^2 - x*W + 4*x^3 - sage: z.characteristic_polynomial('W') # optional - sage.libs.singular sage.modules + sage: z.characteristic_polynomial('W') # optional - sage.modules sage.rings.function_field W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().characteristic_polynomial(*args, **kwds) @@ -338,13 +338,13 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.libs.singular - sage: x.minimal_polynomial('W') # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3); R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^3 - y^2*z + x) # optional - sage.rings.function_field + sage: x.minimal_polynomial('W') # optional - sage.modules sage.rings.function_field W - x - sage: y.minimal_polynomial('W') # optional - sage.libs.singular sage.modules + sage: y.minimal_polynomial('W') # optional - sage.modules sage.rings.function_field W^2 - x*W + 4*x^3 - sage: z.minimal_polynomial('W') # optional - sage.libs.singular sage.modules + sage: z.minimal_polynomial('W') # optional - sage.modules sage.rings.function_field W^3 + (-x*y + 4*x^3)*W + x """ return self.matrix().minimal_polynomial(*args, **kwds) @@ -358,16 +358,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y.is_integral() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: y.is_integral() # optional - sage.rings.function_field True - sage: (y/x).is_integral() # optional - sage.libs.singular sage.modules + sage: (y/x).is_integral() # optional - sage.modules sage.rings.function_field True - sage: (y/x)^2 - (y/x) + 4*x # optional - sage.libs.singular sage.modules + sage: (y/x)^2 - (y/x) + 4*x # optional - sage.modules sage.rings.function_field 0 - sage: (y/x^2).is_integral() # optional - sage.libs.singular sage.modules + sage: (y/x^2).is_integral() # optional - sage.modules sage.rings.function_field False - sage: (y/x).minimal_polynomial('W') # optional - sage.libs.singular sage.modules + sage: (y/x).minimal_polynomial('W') # optional - sage.modules sage.rings.function_field W^2 - W + 4*x """ R = self.parent().base_field().maximal_order() @@ -385,8 +385,8 @@ cdef class FunctionFieldElement(FieldElement): (-1/t^2) d(t) sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari - sage: (y^3 + x).differential() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (y^3 + x).differential() # optional - sage.libs.pari sage.modules sage.rings.function_field (((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3) d(x) TESTS: @@ -395,15 +395,15 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(31)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field + sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari sage.rings.function_field sage: x.differential() # optional - sage.libs.pari sage.modules d(x) - sage: y.differential() # optional - sage.libs.pari sage.modules + sage: y.differential() # optional - sage.libs.pari sage.modules sage.rings.function_field (16/x*y) d(x) - sage: z.differential() # optional - sage.libs.pari sage.modules + sage: z.differential() # optional - sage.libs.pari sage.modules sage.rings.function_field (8/x*z) d(x) """ F = self.parent() @@ -425,8 +425,8 @@ cdef class FunctionFieldElement(FieldElement): (-t^2 - 2*t - 1/3)/(t^4 - 2/3*t^2 + 1/9) sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.modules sage.rings.function_field ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 """ D = self.parent().derivation() @@ -454,8 +454,8 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari sage.modules sage.rings.function_field 1/x^3*y + (x^6 + x^4 + x^3 + x^2 + x + 1)/x^5 """ D = self.parent().higher_derivation() @@ -478,8 +478,8 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: y.divisor() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: y.divisor() # optional - sage.libs.pari sage.modules sage.rings.function_field - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -506,8 +506,8 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari sage.modules sage.rings.function_field 3*Place (x, x*y) """ if self.is_zero(): @@ -533,8 +533,8 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).divisor_of_poles() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (x/y).divisor_of_poles() # optional - sage.libs.pari sage.modules sage.rings.function_field Place (1/x, 1/x*y) + 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -579,8 +579,8 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).poles() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: (x/y).poles() # optional - sage.libs.pari sage.modules sage.rings.function_field [Place (1/x, 1/x*y), Place (x + 1, x*y)] """ return self.divisor_of_poles().support() @@ -596,18 +596,18 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_infinite()[0] # optional - sage.libs.pari sage.modules - sage: y.valuation(p) # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_infinite()[0] # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: y.valuation(p) # optional - sage.libs.pari sage.modules sage.rings.function_field -1 :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: p = O.ideal(x - 1).place() # optional - sage.libs.singular - sage: y.valuation(p) # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.function_field sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.function_field sage.rings.function_field + sage: p = O.ideal(x - 1).place() # optional - sage.rings.function_field sage.rings.function_field + sage: y.valuation(p) # optional - sage.rings.function_field sage.rings.function_field 0 """ prime = place.prime_ideal() @@ -639,14 +639,14 @@ cdef class FunctionFieldElement(FieldElement): :: sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p, = L.places_infinite() # optional - sage.libs.pari - sage: p, = L.places_infinite() # optional - sage.libs.pari - sage: (y + x).evaluate(p) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p, = L.places_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: p, = L.places_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: (y + x).evaluate(p) # optional - sage.libs.pari sage.rings.function_field Traceback (most recent call last): ... ValueError: has a pole at the place - sage: (y/x + 1).evaluate(p) # optional - sage.libs.pari + sage: (y/x + 1).evaluate(p) # optional - sage.libs.pari sage.rings.function_field 1 """ R, fr_R, to_R = place._residue_field() @@ -707,8 +707,8 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L(y^27).nth_root(27) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field + sage: L(y^27).nth_root(27) # optional - sage.libs.pari sage.rings.function_field y """ raise NotImplementedError("nth_root() not implemented for generic elements") diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index 2a542030fda..a794d82f6f2 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.function_field #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee @@ -22,8 +23,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: x*y + 1/x^3 # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: x*y + 1/x^3 x*y + 1/x^3 """ def __init__(self, parent, x, reduce=True): @@ -33,8 +34,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: TestSuite(x*y + 1/x^3).run() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: TestSuite(x*y + 1/x^3).run() """ FieldElement.__init__(self, parent) if reduce: @@ -49,10 +50,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(T^2 - x*T + 4*x^3) # optional - sage.libs.singular - sage: f = y/x^2 + x/(x^2+1); f # optional - sage.libs.singular + sage: L. = K.extension(T^2 - x*T + 4*x^3) + sage: f = y/x^2 + x/(x^2+1); f 1/x^2*y + x/(x^2 + 1) - sage: f.element() # optional - sage.libs.singular + sage: f.element() 1/x^2*y + x/(x^2 + 1) """ return self._x @@ -64,8 +65,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y._repr_() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: y._repr_() 'y' """ return self._x._repr(name=self.parent().variable_name()) @@ -77,12 +78,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: bool(y) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: bool(y) True - sage: bool(L(0)) # optional - sage.libs.singular + sage: bool(L(0)) False - sage: bool(L.coerce(L.polynomial())) # optional - sage.libs.singular + sage: bool(L.coerce(L.polynomial())) False """ return not not self._x @@ -94,8 +95,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) >= 24 True """ return hash(self._x) @@ -107,10 +108,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: L(0) == 0 # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: L(0) == 0 True - sage: y != L(2) # optional - sage.libs.singular + sage: y != L(2) True """ cdef FunctionFieldElement left = self @@ -128,12 +129,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest (5*x + 5)*y + x/(x^3 + 1) - sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest # optional - sage.libs.singular + sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest True - sage: -y + y # optional - sage.libs.singular + sage: -y + y 0 """ cdef FunctionFieldElement res = self._new_c() @@ -151,10 +152,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest (-5*x - 1)*y + x/(x^3 + 1) - sage: y - y # optional - sage.libs.singular + sage: y - y 0 """ cdef FunctionFieldElement res = self._new_c() @@ -172,8 +173,8 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: y * (3*y + 5*x*y) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: y * (3*y + 5*x*y) # indirect doctest (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3 """ cdef FunctionFieldElement res = self._new_c() @@ -191,10 +192,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest 1 - sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest # optional - sage.libs.singular + sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest Traceback (most recent call last): ... ZeroDivisionError: Cannot invert 0 @@ -208,10 +209,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: a = ~(2*y + 1/x); a # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: a = ~(2*y + 1/x); a # indirect doctest (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a*(2*y + 1/x) # optional - sage.libs.singular + sage: a*(2*y + 1/x) 1 """ if self.is_zero(): @@ -229,12 +230,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: a = ~(2*y + 1/x); a # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x*y + 4*x^3) + sage: a = ~(2*y + 1/x); a (-1/8*x^2/(x^5 + 1/8*x^2 + 1/16))*y + (1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16) - sage: a.list() # optional - sage.libs.singular + sage: a.list() [(1/8*x^3 + 1/16*x)/(x^5 + 1/8*x^2 + 1/16), -1/8*x^2/(x^5 + 1/8*x^2 + 1/16)] - sage: (x*y).list() # optional - sage.libs.singular + sage: (x*y).list() [0, x] """ return self._x.padded_list(self._parent.degree()) diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index 18d21e8dba2..f2815c467a5 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -486,8 +486,8 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: O = K.maximal_order(); I = O.ideal(x^2+1) - sage: t = O(x+1).inverse_mod(I); t + sage: O = K.maximal_order(); I = O.ideal(x^2 + 1) + sage: t = O(x + 1).inverse_mod(I); t -1/2*x + 1/2 sage: (t*(x+1) - 1) in I True diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index 6e9d88aee3c..53b10d27f33 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -28,19 +28,19 @@ Constant field extension of a function field over a finite field:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: E # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: E # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^3 + x^6 + x^4 + x^2 over its base - sage: p = F.get_place(3) # optional - sage.libs.pari - sage: E.conorm_place(p) # random # optional - sage.libs.pari + sage: p = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field + sage: E.conorm_place(p) # random # optional - sage.libs.pari sage.rings.function_field Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) + Place (x + z3^2 + z3, y + z3^2) - sage: q = F.get_place(2) # optional - sage.libs.pari - sage: E.conorm_place(q) # random # optional - sage.libs.pari + sage: q = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field + sage: E.conorm_place(q) # random # optional - sage.libs.pari sage.rings.function_field Place (x + 1, y^2 + y + 1) - sage: E.conorm_divisor(p + q) # random # optional - sage.libs.pari + sage: E.conorm_divisor(p + q) # random # optional - sage.libs.pari sage.rings.function_field Place (x + 1, y^2 + y + 1) + Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) @@ -82,9 +82,9 @@ def __init__(self, F, k_ext): TESTS:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) # optional - sage.libs.pari sage.rings.function_field """ k = F.constant_base_field() F_base = F.base_field() @@ -121,9 +121,9 @@ def top(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: E.top() # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: E.top() # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return self._F_ext @@ -137,9 +137,9 @@ def defining_morphism(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: E.defining_morphism() # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: E.defining_morphism() # optional - sage.libs.pari sage.rings.function_field Function Field morphism: From: Function field in y defined by y^3 + x^6 + x^4 + x^2 To: Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -162,15 +162,15 @@ def conorm_place(self, p): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: p = F.get_place(3) # optional - sage.libs.pari - sage: d = E.conorm_place(p) # optional - sage.libs.pari - sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: p = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field + sage: d = E.conorm_place(p) # optional - sage.libs.pari sage.rings.function_field + sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari sage.rings.function_field [1, 1, 1] - sage: p = F.get_place(2) # optional - sage.libs.pari - sage: d = E.conorm_place(p) # optional - sage.libs.pari - sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari + sage: p = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field + sage: d = E.conorm_place(p) # optional - sage.libs.pari sage.rings.function_field + sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari sage.rings.function_field [2] """ embedF = self.defining_morphism() @@ -198,14 +198,14 @@ def conorm_divisor(self, d): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari - sage: p1 = F.get_place(3) # optional - sage.libs.pari - sage: p2 = F.get_place(2) # optional - sage.libs.pari - sage: c = E.conorm_divisor(2*p1+ 3*p2) # optional - sage.libs.pari - sage: c1 = E.conorm_place(p1) # optional - sage.libs.pari - sage: c2 = E.conorm_place(p2) # optional - sage.libs.pari - sage: c == 2*c1 + 3*c2 # optional - sage.libs.pari + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field + sage: p1 = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field + sage: p2 = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field + sage: c = E.conorm_divisor(2*p1 + 3*p2) # optional - sage.libs.pari sage.rings.function_field + sage: c1 = E.conorm_place(p1) # optional - sage.libs.pari sage.rings.function_field + sage: c2 = E.conorm_place(p2) # optional - sage.libs.pari sage.rings.function_field + sage: c == 2*c1 + 3*c2 # optional - sage.libs.pari sage.rings.function_field True """ div_top = self.divisor_group() diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 169d7642f4c..2af6c5231ab 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Function Fields @@ -24,31 +23,31 @@ simple arithmetic in it:: sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: y^2 # optional - sage.libs.pari sage.libs.singular + sage: y^2 # optional - sage.libs.pari sage.rings.function_field y^2 - sage: y^3 # optional - sage.libs.pari sage.libs.singular + sage: y^3 # optional - sage.libs.pari sage.rings.function_field 2*x*y + (x^4 + 1)/x - sage: a = 1/y; a # optional - sage.libs.pari sage.libs.singular + sage: a = 1/y; a # optional - sage.libs.pari sage.rings.function_field (x/(x^4 + 1))*y^2 + 3*x^2/(x^4 + 1) - sage: a * y # optional - sage.libs.pari sage.libs.singular + sage: a * y # optional - sage.libs.pari sage.rings.function_field 1 We next make an extension of the above function field, illustrating that arithmetic with a tower of three fields is fully supported:: sage: S. = L[] # optional - sage.libs.pari - sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari sage.libs.singular - sage: M # optional - sage.libs.pari sage.libs.singular + sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari sage.rings.function_field + sage: M # optional - sage.libs.pari sage.rings.function_field Function field in t defined by t^2 + 4*x*y - sage: t^2 # optional - sage.libs.pari sage.libs.singular + sage: t^2 # optional - sage.libs.pari sage.rings.function_field x*y - sage: 1/t # optional - sage.libs.pari sage.libs.singular + sage: 1/t # optional - sage.libs.pari sage.rings.function_field ((1/(x^4 + 1))*y^2 + 3*x/(x^4 + 1))*t - sage: M.base_field() # optional - sage.libs.pari sage.libs.singular + sage: M.base_field() # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: M.base_field().base_field() # optional - sage.libs.pari sage.libs.singular + sage: M.base_field().base_field() # optional - sage.libs.pari sage.rings.function_field Rational function field in x over Finite Field in a of size 5^2 It is also possible to construct function fields over an imperfect base field:: @@ -60,72 +59,72 @@ sage: J. = FunctionField(GF(5)); J # optional - sage.libs.pari Rational function field in x over Finite Field of size 5 sage: T. = J[] # optional - sage.libs.pari - sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari sage.libs.singular + sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari sage.rings.function_field Function field in v defined by v^5 + 4*x Function fields over the rational field are supported:: sage: F. = FunctionField(QQ) sage: R. = F[] - sage: L. = F.extension(Y^2 - x^8 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(x, y - 1) # optional - sage.libs.singular - sage: P = I.place() # optional - sage.libs.singular - sage: D = P.divisor() # optional - sage.libs.singular - sage: D.basis_function_space() # optional - sage.libs.singular + sage: L. = F.extension(Y^2 - x^8 - 1) # optional - sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.function_field + sage: I = O.ideal(x, y - 1) # optional - sage.rings.function_field + sage: P = I.place() # optional - sage.rings.function_field + sage: D = P.divisor() # optional - sage.rings.function_field + sage: D.basis_function_space() # optional - sage.rings.function_field [1] - sage: (2*D).basis_function_space() # optional - sage.libs.singular + sage: (2*D).basis_function_space() # optional - sage.rings.function_field [1] - sage: (3*D).basis_function_space() # optional - sage.libs.singular + sage: (3*D).basis_function_space() # optional - sage.rings.function_field [1] - sage: (4*D).basis_function_space() # optional - sage.libs.singular + sage: (4*D).basis_function_space() # optional - sage.rings.function_field [1, 1/x^4*y + 1/x^4] sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: I.divisor() # optional - sage.libs.singular + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: I.divisor() # optional - sage.rings.function_field 2*Place (x, y, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, y, (1/(x^3 + x^2 + x))*y^2) sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: I.divisor() # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: I.divisor() # optional - sage.rings.function_field - Place (x, x*y) + Place (x^2 + 1, x*y) Function fields over the algebraic field are supported:: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular sage.rings.number_field - sage: O = L.maximal_order() # optional - sage.libs.singular sage.rings.number_field - sage: I = O.ideal(y) # optional - sage.libs.singular sage.rings.number_field - sage: I.divisor() # optional - sage.libs.singular sage.rings.number_field + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.function_field sage.rings.number_field + sage: O = L.maximal_order() # optional - sage.rings.function_field sage.rings.number_field + sage: I = O.ideal(y) # optional - sage.rings.function_field sage.rings.number_field + sage: I.divisor() # optional - sage.rings.function_field sage.rings.number_field Place (x - I, x*y) - Place (x, x*y) + Place (x + I, x*y) - sage: pl = I.divisor().support()[0] # optional - sage.libs.singular sage.rings.number_field - sage: m = L.completion(pl, prec=5) # optional - sage.libs.singular sage.rings.number_field - sage: m(x) # optional - sage.libs.singular sage.rings.number_field + sage: pl = I.divisor().support()[0] # optional - sage.rings.function_field sage.rings.number_field + sage: m = L.completion(pl, prec=5) # optional - sage.rings.function_field sage.rings.number_field + sage: m(x) # optional - sage.rings.function_field sage.rings.number_field I + s + O(s^5) - sage: m(y) # long time (4s) # optional - sage.libs.singular sage.rings.number_field + sage: m(y) # long time (4s) # optional - sage.rings.function_field sage.rings.number_field -2*s + (-4 - I)*s^2 + (-15 - 4*I)*s^3 + (-75 - 23*I)*s^4 + (-413 - 154*I)*s^5 + O(s^6) - sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.libs.singular sage.rings.number_field + sage: m(y)^2 + m(y) + m(x) + 1/m(x) # long time (8s) # optional - sage.rings.function_field sage.rings.number_field O(s^5) TESTS:: sage: TestSuite(J).run() # optional - sage.libs.pari sage: TestSuite(K).run(max_runs=256) # long time (10s) # optional - sage.rings.number_field - sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.libs.singular sage.rings.number_field + sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.rings.function_field sage.rings.number_field sage: TestSuite(M).run(max_runs=8) # long time (35s) sage: TestSuite(N).run(max_runs=8, skip = '_test_derivation') # long time (15s) - sage: TestSuite(O).run() # optional - sage.libs.singular sage.rings.number_field + sage: TestSuite(O).run() # optional - sage.rings.function_field sage.rings.number_field sage: TestSuite(R).run() - sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.singular sage.libs.pari + sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.pari sage.rings.function_field Global function fields ---------------------- @@ -141,19 +140,19 @@ ideals of those maximal orders:: sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.basis() # optional - sage.libs.pari sage.rings.function_field (1, y, 1/x*y^2 + 1/x*y, 1/x^3*y^3 + 2/x^3*y^2 + 1/x^3*y) - sage: I = O.ideal(x,y); I # optional - sage.libs.pari + sage: I = O.ideal(x,y); I # optional - sage.libs.pari sage.rings.function_field Ideal (x, y) of Maximal order of Function field in y defined by y^4 + y + 2*x^5 - sage: J = I^-1 # optional - sage.libs.pari - sage: J.basis_matrix() # optional - sage.libs.pari + sage: J = I^-1 # optional - sage.libs.pari sage.rings.function_field + sage: J.basis_matrix() # optional - sage.libs.pari sage.rings.function_field [ 1 0 0 0] [1/x 1/x 0 0] [ 0 0 1 0] [ 0 0 0 1] - sage: L.maximal_order_infinite().basis() # optional - sage.libs.pari + sage: L.maximal_order_infinite().basis() # optional - sage.libs.pari sage.rings.function_field (1, 1/x^2*y, 1/x^3*y^2, 1/x^4*y^3) As an example of the most sophisticated computations that Sage can do with a @@ -161,10 +160,10 @@ quartic over `\GF{2}` and gap numbers for ordinary places:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: L.genus() # optional - sage.libs.pari sage.rings.function_field 3 - sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules + sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules sage.rings.function_field [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -175,17 +174,17 @@ Place (x^3 + x^2 + 1, y + x), Place (x^3 + x^2 + 1, y + x^2 + 1), Place (x^3 + x^2 + 1, y + x^2 + x + 1)] - sage: L.gaps() # optional - sage.libs.pari sage.modules + sage: L.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field [1, 2, 3] The gap numbers for Weierstrass places are of course not ordinary:: - sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari sage.modules - sage: p1.gaps() # optional - sage.libs.pari sage.modules + sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: p1.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field [1, 2, 4] - sage: p2.gaps() # optional - sage.libs.pari sage.modules + sage: p2.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field [1, 2, 4] - sage: p3.gaps() # optional - sage.libs.pari sage.modules + sage: p3.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field [1, 2, 4] AUTHORS: @@ -321,8 +320,8 @@ def some_elements(self): :: sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L.some_elements() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: L.some_elements() # optional - sage.rings.function_field [1, y, 1/x*y, @@ -363,8 +362,8 @@ def characteristic(self): sage: K.characteristic() # optional - sage.libs.pari 7 sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L.characteristic() # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field + sage: L.characteristic() # optional - sage.libs.pari sage.rings.function_field 7 """ return self.constant_base_field().characteristic() @@ -421,18 +420,18 @@ def extension(self, f, names=None): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular + sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.rings.function_field Function field in y defined by y^5 + x*y - x^3 - 3*x A nonintegral defining polynomial:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^3 + (1/t)*y + t^3/(t+1), 'z') # optional - sage.libs.singular + sage: K.extension(y^3 + (1/t)*y + t^3/(t+1), 'z') # optional - sage.rings.function_field Function field in z defined by z^3 + 1/t*z + t^3/(t + 1) The defining polynomial need not be monic or integral:: - sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular + sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.rings.function_field Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) """ from . import constructor @@ -458,29 +457,29 @@ def order_with_basis(self, basis, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: O = L.order_with_basis([1, y, y^2]); O # optional - sage.libs.singular + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: O = L.order_with_basis([1, y, y^2]); O # optional - sage.rings.function_field Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular + sage: O.basis() # optional - sage.rings.function_field (1, y, y^2) Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it:: - sage: O = L.order_with_basis([1+y, y, y^2]); O # optional - sage.libs.singular + sage: O = L.order_with_basis([1+y, y, y^2]); O # optional - sage.rings.function_field Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular + sage: O.basis() # optional - sage.rings.function_field (y + 1, y, y^2) The following error is raised when the module spanned by the basis is not closed under multiplication:: - sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O # optional - sage.libs.singular + sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: the module generated by basis (1, x*y + x^2, 2/3*y^2) must be closed under multiplication and this happens when the identity is not in the module spanned by the basis:: - sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2]) # optional - sage.libs.singular + sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2]) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: the identity element must be in the module spanned by basis (x, x*y + x^2, 2/3*y^2) @@ -501,10 +500,10 @@ def order(self, x, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: O = L.order(y); O # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: O = L.order(y); O # optional - sage.modules sage.rings.function_field Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular sage.modules + sage: O.basis() # optional - sage.modules sage.rings.function_field (1, y, y^2) sage: Z = K.order(x); Z # optional - sage.modules @@ -546,24 +545,24 @@ def order_infinite_with_basis(self, basis, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: O = L.order_infinite_with_basis([1, 1/x*y, 1/x^2*y^2]); O # optional - sage.libs.singular + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: O = L.order_infinite_with_basis([1, 1/x*y, 1/x^2*y^2]); O # optional - sage.rings.function_field Infinite order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular + sage: O.basis() # optional - sage.rings.function_field (1, 1/x*y, 1/x^2*y^2) Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1+1/x*y,1/x*y, 1/x^2*y^2]); O # optional - sage.libs.singular + sage: O = L.order_infinite_with_basis([1+1/x*y,1/x*y, 1/x^2*y^2]); O # optional - sage.rings.function_field Infinite order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: O.basis() # optional - sage.libs.singular + sage: O.basis() # optional - sage.rings.function_field (1/x*y + 1, 1/x*y, 1/x^2*y^2) The following error is raised when the module spanned by the basis is not closed under multiplication:: - sage: O = L.order_infinite_with_basis([1,y, 1/x^2*y^2]); O # optional - sage.libs.singular + sage: O = L.order_infinite_with_basis([1,y, 1/x^2*y^2]); O # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2) must be closed under multiplication @@ -571,7 +570,7 @@ def order_infinite_with_basis(self, basis, check=True): and this happens when the identity is not in the module spanned by the basis:: - sage: O = L.order_infinite_with_basis([1/x,1/x*y, 1/x^2*y^2]) # optional - sage.libs.singular + sage: O = L.order_infinite_with_basis([1/x,1/x*y, 1/x^2*y^2]) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: the identity element must be in the module spanned by basis (1/x, 1/x*y, 1/x^2*y^2) @@ -592,8 +591,8 @@ def order_infinite(self, x, check=True): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: L.order_infinite(y) # todo: not implemented # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: L.order_infinite(y) # todo: not implemented # optional - sage.modules sage.rings.function_field sage: Z = K.order(x); Z # optional - sage.modules Order in Rational function field in x over Rational Field @@ -628,15 +627,15 @@ def _coerce_map_from_(self, source): EXAMPLES:: - sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: L.equation_order() # optional - sage.libs.singular + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: L.equation_order() # optional - sage.rings.function_field Order in Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(L.equation_order()) # optional - sage.libs.singular + sage: L._coerce_map_from_(L.equation_order()) # optional - sage.rings.function_field Conversion map: From: Order in Function field in y defined by y^3 + x^3 + 4*x + 1 To: Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari sage.libs.singular + sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari sage.rings.function_field sage: K. = FunctionField(QQ) sage: L. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field @@ -645,18 +644,18 @@ def _coerce_map_from_(self, source): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + 1) # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 1) # optional - sage.libs.pari sage.rings.function_field sage: K. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field sage: R. = K[] # optional - sage.rings.number_field - sage: M. = K.extension(y^3 + 1) # optional - sage.rings.number_field - sage: M.has_coerce_map_from(L) # not tested (the constant field including into a function field is not yet known to be injective) # optional - sage.rings.number_field + sage: M. = K.extension(y^3 + 1) # optional - sage.rings.function_field + sage: M.has_coerce_map_from(L) # not tested (the constant field including into a function field is not yet known to be injective) # optional - sage.rings.function_field True sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(I^2 + 1) # optional - sage.libs.pari + sage: L. = K.extension(I^2 + 1) # optional - sage.libs.pari sage.rings.function_field sage: M. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field - sage: M.has_coerce_map_from(L) # optional - sage.libs.pari sage.rings.number_field + sage: M.has_coerce_map_from(L) # optional - sage.libs.pari sage.rings.function_field sage.rings.number_field True Check that :trac:`31072` is fixed:: @@ -754,8 +753,8 @@ def _convert_map_from_(self, R): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.libs.singular - sage: K(L(x)) # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^3 + x^3 + 4*x + 1) # optional - sage.rings.function_field + sage: K(L(x)) # indirect doctest # optional - sage.rings.function_field x """ from .function_field_polymod import FunctionField_polymod @@ -786,25 +785,28 @@ def _intermediate_fields(self, base): [Rational function field in x over Rational Field] sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L._intermediate_fields(K) # optional - sage.libs.singular - [Function field in y defined by y^2 - x, Rational function field in x over Rational Field] - - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M._intermediate_fields(L) # optional - sage.libs.singular - [Function field in z defined by z^2 - y, Function field in y defined by y^2 - x] - sage: M._intermediate_fields(K) # optional - sage.libs.singular - [Function field in z defined by z^2 - y, Function field in y defined by y^2 - x, + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: L._intermediate_fields(K) # optional - sage.rings.function_field + [Function field in y defined by y^2 - x, + Rational function field in x over Rational Field] + + sage: R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.rings.function_field + sage: M._intermediate_fields(L) # optional - sage.rings.function_field + [Function field in z defined by z^2 - y, + Function field in y defined by y^2 - x] + sage: M._intermediate_fields(K) # optional - sage.rings.function_field + [Function field in z defined by z^2 - y, + Function field in y defined by y^2 - x, Rational function field in x over Rational Field] TESTS:: - sage: K._intermediate_fields(M) # optional - sage.libs.singular + sage: K._intermediate_fields(M) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: field has not been constructed as a finite extension of base - sage: K._intermediate_fields(QQ) # optional - sage.libs.singular + sage: K._intermediate_fields(QQ) # optional - sage.rings.function_field Traceback (most recent call last): ... TypeError: base must be a function field @@ -831,13 +833,13 @@ def rational_function_field(self): Rational function field in x over Rational Field sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L.rational_function_field() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: L.rational_function_field() # optional - sage.rings.function_field Rational function field in x over Rational Field - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.rational_function_field() # optional - sage.libs.singular + sage: R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.rings.function_field + sage: M.rational_function_field() # optional - sage.rings.function_field Rational function field in x over Rational Field """ from .function_field_rational import RationalFunctionField @@ -932,15 +934,15 @@ def valuation(self, prime): valuation ``1/3`` on its uniformizing element `x - w`:: sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(w^3 - t) # optional - sage.libs.pari - sage: N. = FunctionField(L) # optional - sage.libs.pari - sage: w = v.extension(N) # missing factorization, :trac:`16572` # optional - sage.libs.pari + sage: L. = K.extension(w^3 - t) # optional - sage.libs.pari sage.rings.function_field + sage: N. = FunctionField(L) # optional - sage.libs.pari sage.rings.function_field + sage: w = v.extension(N) # missing factorization, :trac:`16572` # optional - sage.libs.pari sage.rings.function_field Traceback (most recent call last): ... NotImplementedError - sage: w(x^3 - t) # not tested # optional - sage.libs.pari + sage: w(x^3 - t) # not tested # optional - sage.libs.pari sage.rings.function_field 1 - sage: w(x - w) # not tested # optional - sage.libs.pari + sage: w(x - w) # not tested # optional - sage.libs.pari sage.rings.function_field 1/3 There are several ways to create valuations on extensions of rational @@ -948,12 +950,12 @@ def valuation(self, prime): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x); L + sage: L. = K.extension(y^2 - x); L # optional - sage.rings.function_field Function field in y defined by y^2 - x A place that has a unique extension can just be defined downstairs:: - sage: v = L.valuation(x); v + sage: v = L.valuation(x); v # optional - sage.rings.function_field (x)-adic valuation """ @@ -971,8 +973,8 @@ def space_of_differentials(self): Space of differentials of Rational function field in t over Rational Field sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_differentials() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ @@ -995,8 +997,8 @@ def space_of_holomorphic_differentials(self): To: Vector space of dimension 0 over Rational Field) sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field + sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field (Vector space of dimension 4 over Finite Field of size 5, Linear map: From: Vector space of dimension 4 over Finite Field of size 5 @@ -1022,8 +1024,8 @@ def basis_of_holomorphic_differentials(self): [] sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field + sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field [((x/(x^3 + 4))*y) d(x), ((1/(x^3 + 4))*y) d(x), ((x/(x^3 + 4))*y^2) d(x), @@ -1044,13 +1046,13 @@ def divisor_group(self): Divisor group of Rational function field in t over Rational Field sage: _. = K[] - sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.libs.singular - sage: L.divisor_group() # optional - sage.modules sage.libs.singular + sage: L. = K.extension(Y^3 - (t^3 - 1)/(t^3 - 2)) # optional - sage.rings.function_field + sage: L.divisor_group() # optional - sage.modules sage.rings.function_field Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.divisor_group() # optional - sage.libs.pari sage.modules + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field + sage: L.divisor_group() # optional - sage.libs.pari sage.modules sage.rings.function_field Divisor group of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ from .divisor import DivisorGroup @@ -1071,8 +1073,8 @@ def place_set(self): Set of places of Rational function field in t over Rational Field sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.place_set() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field Set of places of Function field in y defined by y^2 + y + (x^2 + 1)/x """ from .place import PlaceSet @@ -1097,27 +1099,27 @@ def completion(self, place, name=None, prec=None, gen_name=None): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p); m # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p); m # optional - sage.libs.pari sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x, 10) # optional - sage.libs.pari + sage: m(x, 10) # optional - sage.libs.pari sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y, 10) # optional - sage.libs.pari + sage: m(y, 10) # optional - sage.libs.pari sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p); m # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p); m # optional - sage.libs.pari sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x, 10) # optional - sage.libs.pari + sage: m(x, 10) # optional - sage.libs.pari sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y, 10) # optional - sage.libs.pari + sage: m(y, 10) # optional - sage.libs.pari sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari @@ -1150,29 +1152,29 @@ def completion(self, place, name=None, prec=None, gen_name=None): 0 sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: decomp = O.decomposition(K.maximal_order().ideal(x - 1)) # optional - sage.libs.singular - sage: pls = (decomp[0][0].place(), decomp[1][0].place()) # optional - sage.libs.singular - sage: m = L.completion(pls[0]); m # optional - sage.libs.singular + sage: L. = K.extension(Y^2 - x) # optional - sage.rings.function_field sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.function_field sage.rings.function_field + sage: decomp = O.decomposition(K.maximal_order().ideal(x - 1)) # optional - sage.rings.function_field sage.rings.function_field + sage: pls = (decomp[0][0].place(), decomp[1][0].place()) # optional - sage.rings.function_field sage.rings.function_field + sage: m = L.completion(pls[0]); m # optional - sage.rings.function_field sage.rings.function_field Completion map: From: Function field in y defined by y^2 - x To: Laurent Series Ring in s over Rational Field - sage: xe = m(x) # optional - sage.libs.singular - sage: ye = m(y) # optional - sage.libs.singular - sage: ye^2 - xe == 0 # optional - sage.libs.singular + sage: xe = m(x) # optional - sage.rings.function_field sage.rings.function_field + sage: ye = m(y) # optional - sage.rings.function_field sage.rings.function_field + sage: ye^2 - xe == 0 # optional - sage.rings.function_field sage.rings.function_field True - sage: decomp2 = O.decomposition(K.maximal_order().ideal(x^2 + 1)) # optional - sage.libs.singular - sage: pls2 = decomp2[0][0].place() # optional - sage.libs.singular - sage: m = L.completion(pls2); m # optional - sage.libs.singular + sage: decomp2 = O.decomposition(K.maximal_order().ideal(x^2 + 1)) # optional - sage.rings.function_field sage.rings.function_field + sage: pls2 = decomp2[0][0].place() # optional - sage.rings.function_field sage.rings.function_field + sage: m = L.completion(pls2); m # optional - sage.rings.function_field sage.rings.function_field Completion map: From: Function field in y defined by y^2 - x To: Laurent Series Ring in s over Number Field in a with defining polynomial x^4 + 2*x^2 + 4*x + 2 - sage: xe = m(x) # optional - sage.libs.singular - sage: ye = m(y) # optional - sage.libs.singular - sage: ye^2 - xe == 0 # optional - sage.libs.singular + sage: xe = m(x) # optional - sage.rings.function_field sage.rings.function_field + sage: ye = m(y) # optional - sage.rings.function_field sage.rings.function_field + sage: ye^2 - xe == 0 # optional - sage.rings.function_field sage.rings.function_field True """ from .maps import FunctionFieldCompletion @@ -1189,11 +1191,11 @@ def extension_constant_field(self, k): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: E = F.extension_constant_field(GF(2^4)) # optional - sage.libs.pari - sage: E # optional - sage.libs.pari + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^4)) # optional - sage.libs.pari sage.rings.function_field + sage: E # optional - sage.libs.pari sage.rings.function_field Function field in y defined by y^2 + y + (x^2 + 1)/x over its base - sage: E.constant_base_field() # optional - sage.libs.pari + sage: E.constant_base_field() # optional - sage.libs.pari sage.rings.function_field Finite Field in z4 of size 2^4 """ from .extensions import ConstantFieldExtension diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 04e70275118..6aadac3f1d7 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.rings.function_field + #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee # @@ -42,29 +44,29 @@ class FunctionField_polymod(FunctionField): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x We next make a function field over the above nontrivial function field L:: - sage: S. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 + y*z + y); M # optional - sage.libs.singular + sage: S. = L[] + sage: M. = L.extension(z^2 + y*z + y); M Function field in z defined by z^2 + y*z + y - sage: 1/z # optional - sage.libs.singular + sage: 1/z ((-x/(x^4 + 1))*y^4 + 2*x^2/(x^4 + 1))*z - 1 - sage: z * (1/z) # optional - sage.libs.singular + sage: z * (1/z) 1 We drill down the tower of function fields:: - sage: M.base_field() # optional - sage.libs.singular + sage: M.base_field() Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: M.base_field().base_field() # optional - sage.libs.singular + sage: M.base_field().base_field() Rational function field in x over Rational Field - sage: M.base_field().base_field().constant_field() # optional - sage.libs.singular + sage: M.base_field().base_field().constant_field() Rational Field - sage: M.constant_base_field() # optional - sage.libs.singular + sage: M.constant_base_field() Rational Field .. WARNING:: @@ -77,12 +79,12 @@ class FunctionField_polymod(FunctionField): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x^2 - y^2) # optional - sage.libs.singular - sage: (y - x)*(y + x) # optional - sage.libs.singular + sage: L. = K.extension(x^2 - y^2) + sage: (y - x)*(y + x) 0 - sage: 1/(y - x) # optional - sage.libs.singular + sage: 1/(y - x) 1 - sage: y - x == 0; y + x == 0 # optional - sage.libs.singular + sage: y - x == 0; y + x == 0 False False """ @@ -98,13 +100,13 @@ def __init__(self, polynomial, names, category=None): We create an extension of a function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular + sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L Function field in y defined by y^5 + x*y - x^3 - 3*x - sage: TestSuite(L).run(max_runs=512) # long time (15s) # optional - sage.libs.singular + sage: TestSuite(L).run(max_runs=512) # long time (15s) We can set the variable name, which doesn't have to be y:: - sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L # optional - sage.libs.singular + sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L Function field in w defined by w^5 + x*w - x^3 - 3*x TESTS: @@ -113,12 +115,12 @@ def __init__(self, polynomial, names, category=None): sage: K. = FunctionField(QQ) sage: R. = QQ[] - sage: M. = K.extension(x^7 - x - t) # optional - sage.libs.singular - sage: M(x) # optional - sage.libs.singular + sage: M. = K.extension(x^7 - x - t) + sage: M(x) z - sage: M('z') # optional - sage.libs.singular + sage: M('z') z - sage: M('x') # optional - sage.libs.singular + sage: M('x') Traceback (most recent call last): ... TypeError: unable to evaluate 'x' in Fraction Field of Univariate @@ -161,8 +163,8 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L = K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular - sage: hash(L) == hash(L.polynomial()) # optional - sage.libs.singular + sage: L = K.extension(y^5 - x^3 - 3*x + x*y) + sage: hash(L) == hash(L.polynomial()) True """ return self._hash @@ -178,8 +180,8 @@ def _element_constructor_(self, x): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L._element_constructor_(L.polynomial_ring().gen()) # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L._element_constructor_(L.polynomial_ring().gen()) y """ if isinstance(x, FunctionFieldElement): @@ -195,10 +197,10 @@ def gen(self, n=0): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.gen() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.gen() y - sage: L.gen(1) # optional - sage.libs.singular + sage: L.gen(1) Traceback (most recent call last): ... IndexError: there is only one generator @@ -215,8 +217,8 @@ def ngens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.ngens() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.ngens() 1 """ return 1 @@ -234,10 +236,10 @@ def _to_base_field(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L._to_base_field(L(x)) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: L._to_base_field(L(x)) x - sage: L._to_base_field(y) # optional - sage.libs.singular + sage: L._to_base_field(y) Traceback (most recent call last): ... ValueError: y is not an element of the base field @@ -246,16 +248,16 @@ def _to_base_field(self, f): Verify that :trac:`21872` has been resolved:: - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: R. = L[] + sage: M. = L.extension(z^2 - y) - sage: M(1) in QQ # optional - sage.libs.singular + sage: M(1) in QQ True - sage: M(y) in L # optional - sage.libs.singular + sage: M(y) in L True - sage: M(x) in K # optional - sage.libs.singular + sage: M(x) in K True - sage: z in K # optional - sage.libs.singular + sage: z in K False """ K = self.base_field() @@ -276,10 +278,10 @@ def _to_constant_base_field(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L._to_constant_base_field(L(1)) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: L._to_constant_base_field(L(1)) 1 - sage: L._to_constant_base_field(y) # optional - sage.libs.singular + sage: L._to_constant_base_field(y) Traceback (most recent call last): ... ValueError: y is not an element of the base field @@ -288,9 +290,9 @@ def _to_constant_base_field(self, f): Verify that :trac:`21872` has been resolved:: - sage: L(1) in QQ # optional - sage.libs.singular + sage: L(1) in QQ True - sage: y in QQ # optional - sage.libs.singular + sage: y in QQ False """ return self.base_field()._to_constant_base_field(self._to_base_field(f)) @@ -318,37 +320,37 @@ def monic_integral_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular + sage: L. = K.extension(x^2*y^5 - 1/x); L Function field in y defined by x^2*y^5 - 1/x - sage: A, from_A, to_A = L.monic_integral_model('z') # optional - sage.libs.singular - sage: A # optional - sage.libs.singular + sage: A, from_A, to_A = L.monic_integral_model('z') + sage: A Function field in z defined by z^5 - x^12 - sage: from_A # optional - sage.libs.singular + sage: from_A Function Field morphism: From: Function field in z defined by z^5 - x^12 To: Function field in y defined by x^2*y^5 - 1/x Defn: z |--> x^3*y x |--> x - sage: to_A # optional - sage.libs.singular + sage: to_A Function Field morphism: From: Function field in y defined by x^2*y^5 - 1/x To: Function field in z defined by z^5 - x^12 Defn: y |--> 1/x^3*z x |--> x - sage: to_A(y) # optional - sage.libs.singular + sage: to_A(y) 1/x^3*z - sage: from_A(to_A(y)) # optional - sage.libs.singular + sage: from_A(to_A(y)) y - sage: from_A(to_A(1/y)) # optional - sage.libs.singular + sage: from_A(to_A(1/y)) x^3*y^4 - sage: from_A(to_A(1/y)) == 1/y # optional - sage.libs.singular + sage: from_A(to_A(1/y)) == 1/y True This also works for towers of function fields:: - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2*y - 1/x) # optional - sage.libs.singular - sage: M.monic_integral_model() # optional - sage.libs.singular + sage: R. = L[] + sage: M. = L.extension(z^2*y - 1/x) + sage: M.monic_integral_model() (Function field in z_ defined by z_^10 - x^18, Function Field morphism: From: Function field in z_ defined by z_^10 - x^18 @@ -368,8 +370,8 @@ def monic_integral_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: L.monic_integral_model() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: L.monic_integral_model() (Function field in y defined by y^2 - x, Function Field endomorphism of Function field in y defined by y^2 - x Defn: y |--> y @@ -379,7 +381,7 @@ def monic_integral_model(self, names=None): unless ``names`` does not match with the current names:: - sage: L.monic_integral_model(names=('yy','xx')) # optional - sage.libs.singular + sage: L.monic_integral_model(names=('yy','xx')) (Function field in yy defined by yy^2 - xx, Function Field morphism: From: Function field in yy defined by yy^2 - xx @@ -436,14 +438,14 @@ def _make_monic_integral(self, f): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(x^2*y^5 - 1/x) # optional - sage.libs.singular - sage: g, d = L._make_monic_integral(L.polynomial()); g,d # optional - sage.libs.singular + sage: L. = K.extension(x^2*y^5 - 1/x) + sage: g, d = L._make_monic_integral(L.polynomial()); g,d (y^5 - x^12, x^3) - sage: (y*d).is_integral() # optional - sage.libs.singular + sage: (y*d).is_integral() True - sage: g.is_monic() # optional - sage.libs.singular + sage: g.is_monic() True - sage: g(y*d) # optional - sage.libs.singular + sage: g(y*d) 0 """ R = f.base_ring() @@ -488,13 +490,13 @@ def constant_base_field(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.constant_base_field() # optional - sage.libs.singular + sage: L.constant_base_field() Rational Field - sage: S. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.constant_base_field() # optional - sage.libs.singular + sage: S. = L[] + sage: M. = L.extension(z^2 - y) + sage: M.constant_base_field() Rational Field """ return self.base_field().constant_base_field() @@ -513,23 +515,23 @@ def degree(self, base=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: L.degree() # optional - sage.libs.singular + sage: L.degree() 5 - sage: L.degree(L) # optional - sage.libs.singular + sage: L.degree(L) 1 - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.degree(L) # optional - sage.libs.singular + sage: R. = L[] + sage: M. = L.extension(z^2 - y) + sage: M.degree(L) 2 - sage: M.degree(K) # optional - sage.libs.singular + sage: M.degree(K) 10 TESTS:: - sage: L.degree(M) # optional - sage.libs.singular + sage: L.degree(M) Traceback (most recent call last): ... ValueError: base must be the rational function field itself @@ -549,8 +551,8 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L._repr_() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L._repr_() 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' """ return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial) @@ -564,8 +566,8 @@ def base_field(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.base_field() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.base_field() Rational function field in x over Rational Field """ return self._base_field @@ -578,8 +580,8 @@ def random_element(self, *args, **kwds): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x)) # optional - sage.libs.singular - sage: L.random_element() # random # optional - sage.libs.singular + sage: L. = K.extension(y^2 - (x^2 + x)) + sage: L.random_element() # random ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95) """ @@ -594,8 +596,8 @@ def polynomial(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.polynomial() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.polynomial() y^5 - 2*x*y + (-x^4 - 1)/x """ return self._polynomial @@ -655,8 +657,8 @@ def polynomial_ring(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.polynomial_ring() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.polynomial_ring() Univariate Polynomial Ring in y over Rational function field in x over Rational Field """ return self._ring @@ -695,53 +697,53 @@ def free_module(self, base=None, basis=None, map=True): We define a function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x We get the vector spaces, and maps back and forth:: - sage: V, from_V, to_V = L.free_module() # optional - sage.libs.singular sage.modules - sage: V # optional - sage.libs.singular sage.modules + sage: V, from_V, to_V = L.free_module() # optional - sage.modules + sage: V # optional - sage.modules Vector space of dimension 5 over Rational function field in x over Rational Field - sage: from_V # optional - sage.libs.singular sage.modules + sage: from_V # optional - sage.modules Isomorphism: From: Vector space of dimension 5 over Rational function field in x over Rational Field To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: to_V # optional - sage.libs.singular sage.modules + sage: to_V # optional - sage.modules Isomorphism: From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Vector space of dimension 5 over Rational function field in x over Rational Field We convert an element of the vector space back to the function field:: - sage: from_V(V.1) # optional - sage.libs.singular sage.modules + sage: from_V(V.1) # optional - sage.modules y We define an interesting element of the function field:: - sage: a = 1/L.0; a # optional - sage.libs.singular sage.modules + sage: a = 1/L.0; a # optional - sage.modules (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1) We convert it to the vector space, and get a vector over the base field:: - sage: to_V(a) # optional - sage.libs.singular sage.modules + sage: to_V(a) # optional - sage.modules (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1)) We convert to and back, and get the same element:: - sage: from_V(to_V(a)) == a # optional - sage.libs.singular sage.modules + sage: from_V(to_V(a)) == a # optional - sage.modules True In the other direction:: - sage: v = x*V.0 + (1/x)*V.1 # optional - sage.libs.singular sage.modules - sage: to_V(from_V(v)) == v # optional - sage.libs.singular sage.modules + sage: v = x*V.0 + (1/x)*V.1 # optional - sage.modules + sage: to_V(from_V(v)) == v # optional - sage.modules True And we show how it works over an extension of an extension field:: - sage: R2. = L[]; M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M.free_module() # optional - sage.libs.singular sage.modules + sage: R2. = L[]; M. = L.extension(z^2 - y) + sage: M.free_module() # optional - sage.modules (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism: From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x To: Function field in z defined by z^2 - y, Isomorphism: @@ -750,7 +752,7 @@ def free_module(self, base=None, basis=None, map=True): We can also get the vector space of ``M`` over ``K``:: - sage: M.free_module(K) # optional - sage.libs.singular sage.modules + sage: M.free_module(K) # optional - sage.modules (Vector space of dimension 10 over Rational function field in x over Rational Field, Isomorphism: From: Vector space of dimension 10 over Rational function field in x over Rational Field To: Function field in z defined by z^2 - y, Isomorphism: @@ -778,8 +780,8 @@ def maximal_order(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.maximal_order() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.maximal_order() Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x """ from .order import FunctionFieldMaximalOrder_polymod @@ -792,8 +794,8 @@ def maximal_order_infinite(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.maximal_order_infinite() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: L.maximal_order_infinite() Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari @@ -837,19 +839,19 @@ def equation_order(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.basis() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: O = L.equation_order() + sage: O.basis() (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4) We try an example, in which the defining polynomial is not monic and is not integral:: - sage: K. = FunctionField(QQ); R. = K[] # optional - sage.libs.singular - sage: L. = K.extension(x^2*y^5 - 1/x); L # optional - sage.libs.singular + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(x^2*y^5 - 1/x); L Function field in y defined by x^2*y^5 - 1/x - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.basis() # optional - sage.libs.singular + sage: O = L.equation_order() + sage: O.basis() (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4) """ d = self._make_monic_integral(self.polynomial())[1] @@ -874,40 +876,40 @@ def hom(self, im_gens, base_morphism=None): We create a rational function field, and a quadratic extension of it:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) We make the field automorphism that sends y to -y:: - sage: f = L.hom(-y); f # optional - sage.libs.singular + sage: f = L.hom(-y); f Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 Defn: y |--> -y Evaluation works:: - sage: f(y*x - 1/x) # optional - sage.libs.singular + sage: f(y*x - 1/x) -x*y - 1/x We try to define an invalid morphism:: - sage: f = L.hom(y + 1) # optional - sage.libs.singular + sage: f = L.hom(y + 1) Traceback (most recent call last): ... ValueError: invalid morphism We make a morphism of the base rational function field:: - sage: phi = K.hom(x + 1); phi # optional - sage.libs.singular + sage: phi = K.hom(x + 1); phi Function Field endomorphism of Rational function field in x over Rational Field Defn: x |--> x + 1 - sage: phi(x^3 - 3) # optional - sage.libs.singular + sage: phi(x^3 - 3) x^3 + 3*x^2 + 3*x - 2 - sage: (x+1)^3 - 3 # optional - sage.libs.singular + sage: (x+1)^3 - 3 x^3 + 3*x^2 + 3*x - 2 We make a morphism by specifying where the generators and the base generators go:: - sage: L.hom([-y, x]) # optional - sage.libs.singular + sage: L.hom([-y, x]) Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1 Defn: y |--> -y x |--> x @@ -915,8 +917,8 @@ def hom(self, im_gens, base_morphism=None): You can also specify a morphism on the base:: sage: R1. = K[] - sage: L1. = K.extension(q^2 - (x+1)^3 - 1) # optional - sage.libs.singular - sage: L.hom(q, base_morphism=phi) # optional - sage.libs.singular + sage: L1. = K.extension(q^2 - (x+1)^3 - 1) + sage: L.hom(q, base_morphism=phi) Function Field morphism: From: Function field in y defined by y^2 - x^3 - 1 To: Function field in q defined by q^2 - x^3 - 3*x^2 - 3*x - 2 @@ -926,11 +928,11 @@ def hom(self, im_gens, base_morphism=None): We make another extension of a rational function field:: sage: K2. = FunctionField(QQ); R2. = K2[] - sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) # optional - sage.libs.singular + sage: L2. = K2.extension((4*w)^2 - (t+1)^3 - 1) We define a morphism, by giving the images of generators:: - sage: f = L.hom([4*w, t + 1]); f # optional - sage.libs.singular + sage: f = L.hom([4*w, t + 1]); f Function Field morphism: From: Function field in y defined by y^2 - x^3 - 1 To: Function field in w defined by 16*w^2 - t^3 - 3*t^2 - 3*t - 2 @@ -939,19 +941,19 @@ def hom(self, im_gens, base_morphism=None): Evaluation works, as expected:: - sage: f(y+x) # optional - sage.libs.singular + sage: f(y+x) 4*w + t + 1 - sage: f(x*y + x/(x^2+1)) # optional - sage.libs.singular + sage: f(x*y + x/(x^2+1)) (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2) We make another extension of a rational function field:: sage: K3. = FunctionField(QQ); R3. = K3[] - sage: L3. = K3.extension(yy^2 - xx^3 - 1) # optional - sage.libs.singular + sage: L3. = K3.extension(yy^2 - xx^3 - 1) This is the function field L with the generators exchanged. We define a morphism to L:: - sage: g = L3.hom([x,y]); g # optional - sage.libs.singular + sage: g = L3.hom([x,y]); g Function Field morphism: From: Function field in xx defined by -xx^3 + yy^2 - 1 To: Function field in y defined by y^2 - x^3 - 1 @@ -986,8 +988,8 @@ def genus(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: L.genus() # optional - sage.libs.singular + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)) + sage: L.genus() 3 """ # Unfortunately Singular can not compute the genus with the @@ -1043,10 +1045,10 @@ def _simple_model(self, name='v'): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: M._simple_model() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: R. = L[] + sage: M. = L.extension(z^2 - y) + sage: M._simple_model() (Function field in v defined by v^4 - x, Function Field morphism: From: Function field in v defined by v^4 - x @@ -1172,13 +1174,13 @@ def simple_model(self, name=None): A tower of four function fields:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(z^2 - x); R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(u^2 - z); R. = M[] # optional - sage.libs.singular - sage: N. = M.extension(v^2 - u) # optional - sage.libs.singular + sage: L. = K.extension(z^2 - x); R. = L[] + sage: M. = L.extension(u^2 - z); R. = M[] + sage: N. = M.extension(v^2 - u) The fields N and M as simple extensions of K:: - sage: N.simple_model() # optional - sage.libs.singular + sage: N.simple_model() (Function field in v defined by v^8 - x, Function Field morphism: From: Function field in v defined by v^8 - x @@ -1191,7 +1193,7 @@ def simple_model(self, name=None): u |--> v^2 z |--> v^4 x |--> x) - sage: M.simple_model() # optional - sage.libs.singular + sage: M.simple_model() (Function field in u defined by u^4 - x, Function Field morphism: From: Function field in u defined by u^4 - x @@ -1207,7 +1209,7 @@ def simple_model(self, name=None): An optional parameter ``name`` can be used to set the name of the generator of the simple extension:: - sage: M.simple_model(name='t') # optional - sage.libs.singular + sage: M.simple_model(name='t') (Function field in t defined by t^4 - x, Function Field morphism: From: Function field in t defined by t^4 - x To: Function field in u defined by u^2 - z @@ -1297,16 +1299,16 @@ def primitive_element(self): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: N. = L.extension(z^2 - x - 1) # optional - sage.libs.singular - sage: N.primitive_element() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: R. = L[] + sage: M. = L.extension(z^2 - y) + sage: R. = L[] + sage: N. = L.extension(z^2 - x - 1) + sage: N.primitive_element() u + y - sage: M.primitive_element() # optional - sage.libs.singular + sage: M.primitive_element() z - sage: L.primitive_element() # optional - sage.libs.singular + sage: L.primitive_element() y This also works for inseparable extensions:: @@ -1419,8 +1421,8 @@ def separable_model(self, names=None): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.singular - sage: L.separable_model() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3) + sage: L.separable_model() (Function field in y defined by y^2 - x^3, Function Field endomorphism of Function field in y defined by y^2 - x^3 Defn: y |--> y @@ -1552,11 +1554,11 @@ def change_variable_name(self, name): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^2 - y) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) + sage: R. = L[] + sage: M. = L.extension(z^2 - y) - sage: M.change_variable_name('zz') # optional - sage.libs.singular + sage: M.change_variable_name('zz') (Function field in zz defined by zz^2 - y, Function Field morphism: From: Function field in zz defined by zz^2 - y @@ -1570,7 +1572,7 @@ def change_variable_name(self, name): Defn: z |--> zz y |--> y x |--> x) - sage: M.change_variable_name(('zz','yy')) # optional - sage.libs.singular + sage: M.change_variable_name(('zz','yy')) (Function field in zz defined by zz^2 - yy, Function Field morphism: From: Function field in zz defined by zz^2 - yy To: Function field in z defined by z^2 - y @@ -1582,7 +1584,7 @@ def change_variable_name(self, name): Defn: z |--> zz y |--> yy x |--> x) - sage: M.change_variable_name(('zz','yy','xx')) # optional - sage.libs.singular + sage: M.change_variable_name(('zz','yy','xx')) (Function field in zz defined by zz^2 - yy, Function Field morphism: From: Function field in zz defined by zz^2 - yy @@ -1700,19 +1702,19 @@ def places_above(self, p): True sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = K.maximal_order() # optional - sage.libs.singular - sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] # optional - sage.libs.singular - sage: all(q.place_below() == p # optional - sage.libs.singular + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) + sage: O = K.maximal_order() + sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]] + sage: all(q.place_below() == p ....: for p in pls for q in F.places_above(p)) True sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field - sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.libs.singular sage.rings.number_field + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: pls = [O.ideal(x - QQbar(sqrt(c))).place() # optional - sage.rings.number_field ....: for c in [-2, -1, 0, 1, 2]] - sage: all(q.place_below() == p # long time (4s) # optional - sage.libs.singular sage.rings.number_field + sage: all(q.place_below() == p # long time (4s) # optional - sage.rings.number_field ....: for p in pls for q in F.places_above(p)) True """ @@ -1866,10 +1868,10 @@ class FunctionField_char_zero(FunctionField_simple): EXAMPLES:: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular - sage: L # optional - sage.libs.singular + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) + sage: L Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) - sage: L.characteristic() # optional - sage.libs.singular + sage: L.characteristic() 0 """ @cached_method @@ -1885,8 +1887,8 @@ def higher_derivation(self): EXAMPLES:: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.singular - sage: L.higher_derivation() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) + sage: L.higher_derivation() # optional - sage.modules Higher derivation map: From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2) @@ -2308,11 +2310,11 @@ def _singular_normal(ideal): sage: R. = QQ[] sage: f = (x^2 - y^3) * x - sage: _singular_normal(ideal(f)) # optional - sage.libs.singular + sage: _singular_normal(ideal(f)) [[x, y], [1]] sage: f = y^2 - x - sage: _singular_normal(ideal(f)) # optional - sage.libs.singular + sage: _singular_normal(ideal(f)) [[1]] """ from sage.libs.singular.function import singular_function, lib @@ -2453,8 +2455,8 @@ def equation_order(self): Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: F.equation_order() # optional - sage.libs.singular + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: F.equation_order() Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ from .order import FunctionFieldOrder_basis @@ -2506,8 +2508,8 @@ def equation_order_infinite(self): Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: F.equation_order_infinite() # optional - sage.libs.singular + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: F.equation_order_infinite() Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ from .order import FunctionFieldOrderInfinite_basis diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index 726d939fc54..f36047cda04 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -83,8 +83,8 @@ class RationalFunctionField(FunctionField): sage: R. = FunctionField(QQ) sage: L. = R[] - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular - sage: (y/x).divisor() # optional - sage.libs.singular sage.modules + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.rings.function_field + sage: (y/x).divisor() # optional - sage.rings.function_field sage.modules - Place (x, y - 1) - Place (x, y + 1) + Place (x^2 + 1, y) @@ -93,15 +93,15 @@ class RationalFunctionField(FunctionField): sage: NF. = NumberField(z^2 + 1) # optional - sage.rings.number_field sage: R. = FunctionField(NF) # optional - sage.rings.number_field sage: L. = R[] # optional - sage.rings.number_field - sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.libs.singular sage.modules sage.rings.number_field + sage: F. = R.extension(y^2 - (x^2+1)) # optional - sage.rings.function_field sage.modules sage.rings.number_field - sage: (x/y*x.differential()).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field + sage: (x/y*x.differential()).divisor() # optional - sage.rings.function_field sage.modules sage.rings.number_field -2*Place (1/x, 1/x*y - 1) - 2*Place (1/x, 1/x*y + 1) + Place (x, y - 1) + Place (x, y + 1) - sage: (x/y).divisor() # optional - sage.libs.singular sage.modules sage.rings.number_field + sage: (x/y).divisor() # optional - sage.rings.function_field sage.modules sage.rings.number_field - Place (x - i, y) + Place (x, y - 1) + Place (x, y + 1) @@ -233,8 +233,8 @@ def _element_constructor_(self, x): Some indirect test of conversion:: sage: S. = K[] - sage: I = S * [x^2 - y^2, y - t] # optional - sage.libs.singular - sage: I.groebner_basis() # optional - sage.libs.singular + sage: I = S * [x^2 - y^2, y - t] # optional - sage.rings.function_field + sage: I.groebner_basis() # optional - sage.rings.function_field [x^2 - t^2, y - t] """ @@ -432,18 +432,18 @@ def extension(self, f, names=None): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.libs.singular + sage: K.extension(y^5 - x^3 - 3*x + x*y) # optional - sage.rings.function_field Function field in y defined by y^5 + x*y - x^3 - 3*x A nonintegral defining polynomial:: sage: K. = FunctionField(QQ); R. = K[] - sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular + sage: K.extension(y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.rings.function_field Function field in y defined by y^3 + 1/t*y + t^3/(t + 1) The defining polynomial need not be monic or integral:: - sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.libs.singular + sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1)) # optional - sage.rings.function_field Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1) """ from . import constructor @@ -635,7 +635,7 @@ def hom(self, im_gens, base_morphism=None): We make a map from a rational function field to itself:: sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.hom( (x^4 + 2)/x) # optional - sage.libs.pari + sage: K.hom((x^4 + 2)/x) # optional - sage.libs.pari Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> (x^4 + 2)/x @@ -643,15 +643,15 @@ def hom(self, im_gens, base_morphism=None): non-rational extension field:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari - sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field + sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari sage.rings.function_field Function Field morphism: From: Rational function field in x over Finite Field of size 7 To: Function field in y defined by y^3 + 6*x^3 + x Defn: x |--> y^2 + y + 2 - sage: f(x) # optional - sage.libs.pari + sage: f(x) # optional - sage.libs.pari sage.rings.function_field y^2 + y + 2 - sage: f(x^2) # optional - sage.libs.pari + sage: f(x^2) # optional - sage.libs.pari sage.rings.function_field 5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4 """ if isinstance(im_gens, CategoryObject): diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 6401ecbd581..ee3aebbc165 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -26,46 +26,46 @@ Ideals in the equation order of an extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y); I # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.rings.function_field Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^2 # optional - sage.libs.singular + sage: I^2 # optional - sage.rings.function_field Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 Ideals in the maximal order of a global function field:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I^2 # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I^2 # optional - sage.libs.pari sage.rings.function_field Ideal (x) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari sage.rings.function_field Ideal (1/x*y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I * I # optional - sage.libs.pari + sage: ~I * I # optional - sage.libs.pari sage.rings.function_field Ideal (1) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J = O.ideal(x+y) * I # optional - sage.libs.pari - sage: J.factor() # optional - sage.libs.pari + sage: J = O.ideal(x + y) * I # optional - sage.libs.pari sage.rings.function_field + sage: J.factor() # optional - sage.libs.pari sage.rings.function_field (Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x)^2 * (Ideal (x^3 + x + 1, y + x) of Maximal order of Function field in y defined by y^2 + x^3*y + x) Ideals in the maximal infinite order of a global function field:: sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: I + I == I # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field + sage: I + I == I # optional - sage.libs.pari sage.rings.function_field True - sage: I^2 # optional - sage.libs.pari + sage: I^2 # optional - sage.libs.pari sage.rings.function_field Ideal (1/x^4*y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I # optional - sage.libs.pari + sage: ~I # optional - sage.libs.pari sage.rings.function_field Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I * I # optional - sage.libs.pari + sage: ~I * I # optional - sage.libs.pari sage.rings.function_field Ideal (1) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: I.factor() # optional - sage.libs.pari + sage: I.factor() # optional - sage.libs.pari sage.rings.function_field (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^4 AUTHORS: @@ -136,10 +136,10 @@ def _repr_short(self): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: I._repr_short() # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field + sage: I._repr_short() # optional - sage.libs.pari sage.rings.function_field '(1/x^4*y^2)' """ if self.is_zero(): @@ -155,24 +155,24 @@ def _repr_(self): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x,1/(x+1)); I + sage: I = O.ideal(x, 1/(x+1)); I Ideal (1/(x + 1)) of Maximal order of Rational function field in x over Rational Field sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.ideal(x^2 + 1) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.ideal(x^2 + 1) # optional - sage.libs.pari sage.rings.function_field Ideal (x^2 + 1) of Order in Function field in y defined by y^2 - x^3 - 1 sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.libs.pari sage.rings.function_field Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.libs.pari sage.rings.function_field Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x @@ -184,16 +184,16 @@ def _repr_(self): in x over Finite Field of size 2 sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(1/y) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(1/y) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -209,10 +209,10 @@ def _latex_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: latex(I) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: latex(I) # optional - sage.libs.pari sage.rings.function_field \left(y\right) """ return '\\left(' + ', '.join(latex(g) for g in self.gens_reduced()) + '\\right)' @@ -288,10 +288,10 @@ def base_ring(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular - sage: I.base_ring() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(x^2 + 1) # optional - sage.rings.function_field + sage: I.base_ring() # optional - sage.rings.function_field Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring() @@ -309,7 +309,7 @@ def place(self): Traceback (most recent call last): ... TypeError: not a prime ideal - sage: I = O.ideal(x^3+x+1) # optional - sage.libs.pari + sage: I = O.ideal(x^3 + x + 1) # optional - sage.libs.pari sage: I.place() # optional - sage.libs.pari Place (x^3 + x + 1) @@ -321,44 +321,44 @@ def place(self): Place (1/x) sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari sage.rings.function_field [Place (x, (1/(x^3 + x^2 + x))*y^2), Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2)] sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari sage.rings.function_field [Place (x, x*y), Place (x + 1, x*y)] sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari sage.rings.function_field + sage: I.factor() # optional - sage.libs.pari sage.rings.function_field (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.libs.pari sage.rings.function_field + sage: J.is_prime() # optional - sage.libs.pari sage.rings.function_field True - sage: J.place() # optional - sage.libs.pari + sage: J.place() # optional - sage.libs.pari sage.rings.function_field Place (1/x, 1/x^3*y^2) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari sage.rings.function_field + sage: I.factor() # optional - sage.libs.pari sage.rings.function_field (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.libs.pari sage.rings.function_field + sage: J.is_prime() # optional - sage.libs.pari sage.rings.function_field True - sage: J.place() # optional - sage.libs.pari + sage: J.place() # optional - sage.libs.pari sage.rings.function_field Place (1/x, 1/x*y) """ if not self.is_prime(): @@ -392,33 +392,33 @@ def factor(self): over Finite Field in z2 of size 2^2)^2 sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I == I.factor().prod() # optional - sage.libs.pari + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I == I.factor().prod() # optional - sage.libs.pari sage.rings.function_field True - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: f= 1/x # optional - sage.libs.pari - sage: I = Oinf.ideal(f) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: f= 1/x # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(f) # optional - sage.libs.pari sage.rings.function_field + sage: I.factor() # optional - sage.libs.pari sage.rings.function_field (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2) * (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2) sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: I == I.factor().prod() # optional - sage.libs.singular + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: I == I.factor().prod() # optional - sage.rings.function_field True sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: I == I.factor().prod() # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: I == I.factor().prod() # optional - sage.rings.function_field True """ @@ -442,30 +442,30 @@ def divisor(self): 2*Place (1/x) sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(y) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field -2*Place (1/x, 1/x^4*y^2 + 1/x^2*y + 1) - 2*Place (1/x, 1/x^2*y + 1) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field - Place (x, x*y) + 2*Place (x + 1, x*y) - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(y) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field - Place (1/x, 1/x*y) """ from .divisor import divisor @@ -496,10 +496,10 @@ def divisor_of_zeros(self): 2*Place (1/x) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I.divisor_of_zeros() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor_of_zeros() # optional - sage.libs.pari sage.rings.function_field 2*Place (x + 1, x*y) """ from .divisor import divisor @@ -530,10 +530,10 @@ def divisor_of_poles(self): 0 sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I.divisor_of_poles() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field + sage: I.divisor_of_poles() # optional - sage.libs.pari sage.rings.function_field Place (x, x*y) """ from .divisor import divisor @@ -562,12 +562,12 @@ class FunctionFieldIdeal_module(FunctionFieldIdeal, Ideal_generic): An ideal in an extension of a rational function field:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: I # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: I # optional - sage.rings.function_field Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^2 # optional - sage.libs.singular + sage: I^2 # optional - sage.rings.function_field Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ def __init__(self, ring, module): @@ -577,10 +577,10 @@ def __init__(self, ring, module): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: TestSuite(I).run() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: TestSuite(I).run() # optional - sage.rings.function_field """ FunctionFieldIdeal.__init__(self, ring) @@ -600,15 +600,15 @@ def __contains__(self, x): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y); I # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.rings.function_field Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: y in I # optional - sage.libs.singular + sage: y in I # optional - sage.rings.function_field True - sage: y/x in I # optional - sage.libs.singular + sage: y/x in I # optional - sage.rings.function_field False - sage: y^2 - 2 in I # optional - sage.libs.singular + sage: y^2 - 2 in I # optional - sage.rings.function_field False """ return self._structure[2](x) in self._module @@ -620,10 +620,10 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: d = {I: 1} # indirect doctest # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: d = {I: 1} # indirect doctest # optional - sage.rings.function_field """ return hash((self._ring,self._module)) @@ -634,18 +634,18 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(x, y); J = O.ideal(y^2 - 2) # optional - sage.libs.singular - sage: I + J == J + I # indirect test # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(x, y); J = O.ideal(y^2 - 2) # optional - sage.rings.function_field + sage: I + J == J + I # indirect test # optional - sage.rings.function_field True - sage: I + I == I # indirect doctest # optional - sage.libs.singular + sage: I + I == I # indirect doctest # optional - sage.rings.function_field True - sage: I == J # optional - sage.libs.singular + sage: I == J # optional - sage.rings.function_field False - sage: I < J # optional - sage.libs.singular + sage: I < J # optional - sage.rings.function_field True - sage: J < I # optional - sage.libs.singular + sage: J < I # optional - sage.rings.function_field False """ return richcmp(self.module().basis(), other.module().basis(), op) @@ -665,20 +665,20 @@ def module(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order(); O # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.rings.function_field Order in Function field in y defined by y^2 - x^3 - 1 - sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular - sage: I.gens() # optional - sage.libs.singular + sage: I = O.ideal(x^2 + 1) # optional - sage.rings.function_field + sage: I.gens() # optional - sage.rings.function_field (x^2 + 1, (x^2 + 1)*y) - sage: I.module() # optional - sage.libs.singular + sage: I.module() # optional - sage.rings.function_field Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Rational Field Echelon basis matrix: [x^2 + 1 0] [ 0 x^2 + 1] - sage: V, from_V, to_V = L.vector_space(); V # optional - sage.libs.singular + sage: V, from_V, to_V = L.vector_space(); V # optional - sage.rings.function_field Vector space of dimension 2 over Rational function field in x over Rational Field - sage: I.module().is_submodule(V) # optional - sage.libs.singular + sage: I.module().is_submodule(V) # optional - sage.rings.function_field True """ return self._module @@ -690,10 +690,10 @@ def gens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular - sage: I.gens() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(x^2 + 1) # optional - sage.rings.function_field + sage: I.gens() # optional - sage.rings.function_field (x^2 + 1, (x^2 + 1)*y) """ return self._gens @@ -705,10 +705,10 @@ def gen(self, i): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular - sage: I.gen(1) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(x^2 + 1) # optional - sage.rings.function_field + sage: I.gen(1) # optional - sage.rings.function_field (x^2 + 1)*y """ return self._gens[i] @@ -720,10 +720,10 @@ def ngens(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(x^2 + 1) # optional - sage.libs.singular - sage: I.ngens() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(x^2 + 1) # optional - sage.rings.function_field + sage: I.ngens() # optional - sage.rings.function_field 2 """ return len(self._gens) @@ -735,11 +735,11 @@ def _add_(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: J = O.ideal(x+y) # optional - sage.libs.singular - sage: I + J # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: J = O.ideal(x+y) # optional - sage.rings.function_field + sage: I + J # optional - sage.rings.function_field Ideal ((-x^2 + x)*y + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal(self.gens() + other.gens()) @@ -751,11 +751,11 @@ def _mul_(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: J = O.ideal(x+y) # optional - sage.libs.singular - sage: I * J # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: J = O.ideal(x+y) # optional - sage.rings.function_field + sage: I * J # optional - sage.rings.function_field Ideal ((-x^5 + x^4 - x^2 + x)*y + x^3 + 1, (x^3 - x^2 + 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal([x*y for x in self.gens() for y in other.gens()]) @@ -767,10 +767,10 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: x * I # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: x * I # optional - sage.rings.function_field Ideal (x^4 + x, -x*y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ring().ideal([other * x for x in self.gens()]) @@ -782,14 +782,14 @@ def intersection(self, other): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y^3); J = O.ideal(y^2) # optional - sage.libs.singular - sage: Z = I.intersection(J); Z # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y^3); J = O.ideal(y^2) # optional - sage.rings.function_field + sage: Z = I.intersection(J); Z # optional - sage.rings.function_field Ideal (x^6 + 2*x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: y^2 in Z # optional - sage.libs.singular + sage: y^2 in Z # optional - sage.rings.function_field False - sage: y^3 in Z # optional - sage.libs.singular + sage: y^3 in Z # optional - sage.rings.function_field True """ if not isinstance(other, FunctionFieldIdeal): @@ -812,14 +812,14 @@ def __invert__(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: ~I # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: ~I # optional - sage.rings.function_field Ideal (-1, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: I^-1 # optional - sage.libs.singular + sage: I^-1 # optional - sage.rings.function_field Ideal (-1, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: ~I * I # optional - sage.libs.singular + sage: ~I * I # optional - sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 - x^3 - 1 """ if len(self.gens()) == 0: @@ -858,9 +858,9 @@ class FunctionFieldIdealInfinite_module(FunctionFieldIdealInfinite, Ideal_generi EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.ideal(y) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: O.ideal(y) # optional - sage.rings.function_field Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ def __init__(self, ring, module): @@ -870,10 +870,10 @@ def __init__(self, ring, module): TESTS:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: TestSuite(I).run() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.function_field + sage: TestSuite(I).run() # optional - sage.rings.function_field """ FunctionFieldIdealInfinite.__init__(self, ring) @@ -898,15 +898,15 @@ def __contains__(self, x): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari + sage: y in I # optional - sage.libs.pari sage.rings.function_field True - sage: y/x in I # optional - sage.libs.pari + sage: y/x in I # optional - sage.libs.pari sage.rings.function_field False - sage: y^2 - 2 in I # optional - sage.libs.pari + sage: y^2 - 2 in I # optional - sage.libs.pari sage.rings.function_field True """ return self._structure[2](x) in self._module @@ -918,10 +918,10 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari - sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari sage.rings.function_field + sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari sage.rings.function_field """ return hash((self._ring,self._module)) @@ -936,10 +936,10 @@ def __eq__(self, other): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari - sage: I == I + I # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari sage.rings.function_field + sage: I == I + I # indirect doctest # optional - sage.libs.pari sage.rings.function_field True """ if not isinstance(other, FunctionFieldIdeal_module): diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index 47fdf7b66b5..fae17dba8f8 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.rings.function_field + #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee # @@ -98,8 +100,8 @@ def __bool__(self): sage: J.is_zero() # optional - sage.libs.pari True - sage: K.=FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari - sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y); I # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y @@ -169,29 +171,29 @@ def __contains__(self, x): False sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal([y]); I # optional - sage.libs.singular + sage: L. = K.extension(Y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: I = O.ideal([y]); I Ideal (y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: x * y in I # optional - sage.libs.singular + sage: x * y in I True - sage: y / x in I # optional - sage.libs.singular + sage: y / x in I False - sage: y^2 - 2 in I # optional - sage.libs.singular + sage: y^2 - 2 in I False - sage: K. = FunctionField(QQ); _. = K[] # optional - sage.libs.singular - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal([y]); I # optional - sage.libs.singular + sage: K. = FunctionField(QQ); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: O = L.maximal_order() + sage: I = O.ideal([y]); I Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I # optional - sage.libs.singular + sage: x * y in I True - sage: y / x in I # optional - sage.libs.singular + sage: y / x in I False - sage: y^2 - 2 in I # optional - sage.libs.singular + sage: y^2 - 2 in I False """ from sage.modules.free_module_element import vector @@ -240,29 +242,29 @@ def __invert__(self): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: ~I # optional - sage.libs.singular + sage: L. = K.extension(Y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: I = O.ideal(y) + sage: ~I Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: I^(-1) # optional - sage.libs.singular + sage: I^(-1) Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 - x^3 - 1 - sage: ~I * I # optional - sage.libs.singular + sage: ~I * I Ideal (1) of Maximal order of Function field in y defined by y^2 - x^3 - 1 :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: ~I # optional - sage.libs.singular + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: O = L.maximal_order() + sage: I = O.ideal(y) + sage: ~I Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) # optional - sage.libs.singular + sage: I^(-1) Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I # optional - sage.libs.singular + sage: ~I * I Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ R = self.ring() @@ -319,14 +321,14 @@ def _add_(self, other): sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari sage: I + J # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari sage: I + J # optional - sage.libs.pari Ideal (1, y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -346,7 +348,7 @@ def _mul_(self, other): sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari sage: I * J # optional - sage.libs.pari Ideal (x^4 + x^2 + x, x*y + x^2) of Maximal order of Function field in y defined by y^2 + x^3*y + x @@ -354,7 +356,7 @@ def _mul_(self, other): sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x+y) # optional - sage.libs.pari + sage: J = O.ideal(x + y) # optional - sage.libs.pari sage: I * J # optional - sage.libs.pari Ideal ((x + 1)*y + (x^2 + 1)/x) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x @@ -396,14 +398,14 @@ def _acted_upon_(self, other, on_left): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: J = O.ideal(x) # optional - sage.libs.pari sage: x * I == I * J # optional - sage.libs.pari True sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: J = O.ideal(x) # optional - sage.libs.pari sage: x * I == I * J # optional - sage.libs.pari True @@ -436,7 +438,7 @@ def intersect(self, other): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: J = O.ideal(x) # optional - sage.libs.pari sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.libs.pari True @@ -488,9 +490,9 @@ def hnf(self): :: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: I = O.ideal(y*(y+1)); I.hnf() [x^6 + x^3 0] [ x^3 + 1 1] """ @@ -514,12 +516,12 @@ def denominator(self): :: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y/(y+1)) # optional - sage.libs.singular - sage: d = I.denominator(); d # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) + sage: O = L.maximal_order() + sage: I = O.ideal(y/(y+1)) + sage: d = I.denominator(); d x^3 - sage: d in O # optional - sage.libs.singular + sage: d in O True """ return self._denominator @@ -535,7 +537,7 @@ def module(self): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.module() # optional - sage.libs.pari Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 @@ -559,13 +561,13 @@ def gens_over_base(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens_over_base() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens_over_base() # optional - sage.libs.pari (x^3 + 1, y + x) """ @@ -604,13 +606,13 @@ def gens(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x^3 + 1, y + x) """ @@ -627,9 +629,9 @@ def basis_matrix(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.libs.pari True """ @@ -647,9 +649,9 @@ def is_integral(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.is_integral() # optional - sage.libs.pari False sage: J = I.denominator() * I # optional - sage.libs.pari @@ -659,7 +661,7 @@ def is_integral(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.is_integral() # optional - sage.libs.pari False sage: J = I.denominator() * I # optional - sage.libs.pari @@ -667,13 +669,13 @@ def is_integral(self): True sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular - sage: I.is_integral() # optional - sage.libs.singular + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: O = F.maximal_order() + sage: I = O.ideal(x, 1/y) + sage: I.is_integral() False - sage: J = I.denominator() * I # optional - sage.libs.singular - sage: J.is_integral() # optional - sage.libs.singular + sage: J = I.denominator() * I + sage: J.is_integral() True """ return self.denominator() == 1 @@ -687,9 +689,9 @@ def ideal_below(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.ideal_below() # optional - sage.libs.pari Traceback (most recent call last): ... @@ -702,7 +704,7 @@ def ideal_below(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x,1/y) # optional - sage.libs.pari + sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari sage: I.ideal_below() # optional - sage.libs.pari Traceback (most recent call last): ... @@ -713,15 +715,15 @@ def ideal_below(self): in x over Finite Field of size 2 sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(x, 1/y) # optional - sage.libs.singular - sage: I.ideal_below() # optional - sage.libs.singular + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: O = F.maximal_order() + sage: I = O.ideal(x, 1/y) + sage: I.ideal_below() Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.singular - sage: J.ideal_below() # optional - sage.libs.singular + sage: J = I.denominator() * I + sage: J.ideal_below() Ideal (x^3 + x^2 + x) of Maximal order of Rational function field in x over Rational Field """ @@ -753,7 +755,7 @@ def norm(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari sage: i1 = O.ideal(x) # optional - sage.libs.pari sage: i2 = O.ideal(y) # optional - sage.libs.pari @@ -799,7 +801,7 @@ def is_prime(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari @@ -813,10 +815,10 @@ def is_prime(self): [True, True] sage: K. = FunctionField(QQ); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.singular + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) + sage: O = F.maximal_order() + sage: I = O.ideal(y) + sage: [f.is_prime() for f,_ in I.factor()] [True, True] """ factors = self.factor() @@ -933,10 +935,10 @@ def prime_below(self): Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] sage: K. = FunctionField(QQ); _. = K[] - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.singular - sage: O = F.maximal_order() # optional - sage.libs.singular - sage: I = O.ideal(y) # optional - sage.libs.singular - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.singular + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) + sage: O = F.maximal_order() + sage: I = O.ideal(y) + sage: [f.prime_below() for f,_ in I.factor()] [Ideal (x) of Maximal order of Rational function field in x over Rational Field, Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Rational Field] """ @@ -949,7 +951,7 @@ def _factor(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(y) # optional - sage.libs.pari sage: I == I.factor().prod() # indirect doctest # optional - sage.libs.pari @@ -1069,13 +1071,13 @@ def gens(self): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 +Y + x + 1/x) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x+y) # optional - sage.libs.pari + sage: I = O.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x^3 + 1, y + x) """ @@ -1148,13 +1150,13 @@ def _gens_two(self): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2,x*y,x+y) # optional - sage.libs.pari + sage: I = O.ideal(x^2, x*y, x + y) # optional - sage.libs.pari sage: I._gens_two() # optional - sage.libs.pari (x, y) sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari sage: _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y-x) # optional - sage.libs.pari + sage: L. = K.extension(Y - x) # optional - sage.libs.pari sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.libs.pari (x,) """ @@ -1257,7 +1259,7 @@ class FunctionFieldIdealInfinite_polymod(FunctionFieldIdealInfinite): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: Oinf.ideal(1/y) # optional - sage.libs.pari Ideal (1/x^4*y^2) of Maximal infinite order of Function field @@ -1270,7 +1272,7 @@ def __init__(self, ring, ideal): TESTS:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari sage: TestSuite(I).run() # optional - sage.libs.pari @@ -1334,7 +1336,7 @@ def _add_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari @@ -1364,7 +1366,7 @@ def _mul_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari @@ -1390,7 +1392,7 @@ def __pow__(self, n): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari sage: J^3 # optional - sage.libs.pari @@ -1436,7 +1438,7 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari @@ -1491,16 +1493,16 @@ def gens(self): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x, y, 1/x^2*y^2) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x, y) """ @@ -1515,16 +1517,16 @@ def gens_two(self): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari sage: I.gens_two() # optional - sage.libs.pari (x, y) sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2+Y+x+1/x) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+y) # optional - sage.libs.pari + sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari sage: I.gens_two() # optional - sage.libs.pari (x,) """ @@ -1607,7 +1609,7 @@ def prime_below(self): EXAMPLES:: sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3+t^2-x^4) # optional - sage.libs.pari + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari sage: I.factor() # optional - sage.libs.pari @@ -1651,8 +1653,8 @@ def valuation(self, ideal): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L.=K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari @@ -1670,9 +1672,9 @@ def _factor(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3-x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: f= 1/x # optional - sage.libs.pari + sage: f = 1/x # optional - sage.libs.pari sage: I = Oinf.ideal(f) # optional - sage.libs.pari sage: I._factor() # optional - sage.libs.pari [(Ideal (1/x, 1/x^4*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 72decf69121..d15861aeff9 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -91,12 +91,12 @@ def _richcmp_(self, other, op): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+1) - sage: J = O.ideal(x^2+x+1,x) + sage: I = O.ideal(x, x^2 + 1) + sage: J = O.ideal(x^2 + x + 1, x) sage: I == J True sage: I = O.ideal(x) - sage: J = O.ideal(x+1) + sage: J = O.ideal(x + 1) sage: I < J True """ @@ -114,8 +114,8 @@ def _add_(self, other): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+1) - sage: J = O.ideal(x^2+x+1,x) + sage: I = O.ideal(x, x^2 + 1) + sage: J = O.ideal(x^2 + x + 1, x) sage: I + J == J + I True """ @@ -133,8 +133,8 @@ def _mul_(self, other): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x,x^2+x) - sage: J = O.ideal(x^2,x) + sage: I = O.ideal(x, x^2 + x) + sage: J = O.ideal(x^2, x) sage: I * J == J * I True """ @@ -152,7 +152,7 @@ def _acted_upon_(self, other, on_left): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x^3+x^2) + sage: I = O.ideal(x^3 + x^2) sage: 2 * I Ideal (x^3 + x^2) of Maximal order of Rational function field in x over Rational Field sage: x * I @@ -212,7 +212,7 @@ def module(self): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() - sage: I = O.ideal(x^3+x^2) + sage: I = O.ideal(x^3 + x^2) sage: I.module() # optional - sage.modules Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Rational Field @@ -236,7 +236,7 @@ def gen(self): sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari sage: I.gen() # optional - sage.libs.pari x^2 + x """ @@ -250,7 +250,7 @@ def gens(self): sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (x^2 + x,) """ @@ -265,7 +265,7 @@ def gens_over_base(self): sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2+x) # optional - sage.libs.pari + sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari sage: I.gens_over_base() # optional - sage.libs.pari (x^2 + x,) """ @@ -307,7 +307,7 @@ def _valuation(self, ideal): sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: p = O.ideal(x) - sage: p.valuation(O.ideal(x+1)) # indirect doctest + sage: p.valuation(O.ideal(x + 1)) # indirect doctest 0 sage: p.valuation(O.ideal(x^2)) # indirect doctest 2 @@ -416,8 +416,8 @@ def _richcmp_(self, other, op): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x+1) # optional - sage.libs.pari - sage: J = Oinf.ideal(x^2+x) # optional - sage.libs.pari + sage: I = Oinf.ideal(x + 1) # optional - sage.libs.pari + sage: J = Oinf.ideal(x^2 + x) # optional - sage.libs.pari sage: I + J == J # optional - sage.libs.pari True """ @@ -520,7 +520,7 @@ def gen(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari sage: I.gen() # optional - sage.libs.pari 1/x^2 """ @@ -534,7 +534,7 @@ def gens(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari sage: I.gens() # optional - sage.libs.pari (1/x^2,) """ @@ -549,7 +549,7 @@ def gens_over_base(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x),(x^2+1)/x^4) # optional - sage.libs.pari + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari sage: I.gens_over_base() # optional - sage.libs.pari (1/x^2,) """ diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index f09be93318c..951cc8bd73e 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Morphisms of function fields @@ -10,17 +9,17 @@ sage: K.hom(1/x) Function Field endomorphism of Rational function field in x over Rational Field Defn: x |--> 1/x - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: K.hom(y) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: K.hom(y) # optional - sage.rings.function_field Function Field morphism: From: Rational function field in x over Rational Field To: Function field in y defined by y^2 - x Defn: x |--> y - sage: L.hom([y,x]) # optional - sage.libs.singular + sage: L.hom([y,x]) # optional - sage.rings.function_field Function Field endomorphism of Function field in y defined by y^2 - x Defn: y |--> y x |--> x - sage: L.hom([x,y]) # optional - sage.libs.singular + sage: L.hom([x,y]) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: invalid morphism @@ -72,9 +71,9 @@ class FunctionFieldVectorSpaceIsomorphism(Morphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldVectorSpaceIsomorphism) # optional - sage.modules sage.rings.function_field True """ def _repr_(self) -> str: @@ -84,13 +83,13 @@ def _repr_(self) -> str: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f # optional - sage.modules sage.rings.function_field Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 - sage: t # optional - sage.libs.singular sage.modules + sage: t # optional - sage.modules sage.rings.function_field Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -107,9 +106,9 @@ def is_injective(self) -> bool: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f.is_injective() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f.is_injective() # optional - sage.modules sage.rings.function_field True """ return True @@ -121,9 +120,9 @@ def is_surjective(self) -> bool: EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f.is_surjective() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f.is_surjective() # optional - sage.modules sage.rings.function_field True """ return True @@ -187,8 +186,8 @@ class MapVectorSpaceToFunctionField(FunctionFieldVectorSpaceIsomorphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); f # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space(); f # optional - sage.modules sage.rings.function_field Isomorphism: From: Vector space of dimension 2 over Rational function field in x over Rational Field To: Function field in y defined by y^2 - x*y + 4*x^3 @@ -198,8 +197,8 @@ def __init__(self, V, K): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); type(f) # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space(); type(f) # optional - sage.modules sage.rings.function_field """ self._V = V @@ -219,18 +218,18 @@ def _call_(self, v): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest # optional - sage.modules sage.rings.function_field 1/x^3*y + x TESTS: Test that this map is a bijection for some random inputs:: - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular - sage: for F in [K, L, M]: # optional - sage.libs.singular sage.modules + sage: R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^3 - y - x) # optional - sage.rings.function_field + sage: for F in [K, L, M]: # optional - sage.modules sage.rings.function_field ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -262,9 +261,9 @@ def domain(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f.domain() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f.domain() # optional - sage.modules sage.rings.function_field Vector space of dimension 2 over Rational function field in x over Rational Field """ return self._V @@ -276,9 +275,9 @@ def codomain(self): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: f.codomain() # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: f.codomain() # optional - sage.modules sage.rings.function_field Function field in y defined by y^2 - x*y + 4*x^3 """ return self._K @@ -291,8 +290,8 @@ class MapFunctionFieldToVectorSpace(FunctionFieldVectorSpaceIsomorphism): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space(); t # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space(); t # optional - sage.modules sage.rings.function_field Isomorphism: From: Function field in y defined by y^2 - x*y + 4*x^3 To: Vector space of dimension 2 over Rational function field in x over Rational Field @@ -310,9 +309,9 @@ def __init__(self, K, V): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: TestSuite(t).run(skip="_test_category") # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: TestSuite(t).run(skip="_test_category") # optional - sage.modules sage.rings.function_field """ self._V = V self._K = K @@ -327,18 +326,18 @@ def _call_(self, x): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.libs.singular - sage: V, f, t = L.vector_space() # optional - sage.libs.singular sage.modules - sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.libs.singular sage.modules + sage: L. = K.extension(y^2 - x*y + 4*x^3) # optional - sage.rings.function_field + sage: V, f, t = L.vector_space() # optional - sage.modules sage.rings.function_field + sage: t(x + (1/x^3)*y) # indirect doctest # optional - sage.modules sage.rings.function_field (x, 1/x^3) TESTS: Test that this map is a bijection for some random inputs:: - sage: R. = L[] # optional - sage.libs.singular - sage: M. = L.extension(z^3 - y - x) # optional - sage.libs.singular - sage: for F in [K, L, M]: # optional - sage.libs.singular sage.modules + sage: R. = L[] # optional - sage.rings.function_field + sage: M. = L.extension(z^3 - y - x) # optional - sage.rings.function_field + sage: for F in [K, L, M]: # optional - sage.modules sage.rings.function_field ....: for base in F._intermediate_fields(K): ....: V, f, t = F.vector_space(base) ....: for i in range(100): @@ -392,9 +391,9 @@ def _repr_type(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular - sage: f._repr_type() # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field + sage: f._repr_type() # optional - sage.libs.pari sage.rings.function_field 'Function Field' """ return "Function Field" @@ -406,9 +405,9 @@ def _repr_defn(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular - sage: f._repr_defn() # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field + sage: f._repr_defn() # optional - sage.libs.pari sage.rings.function_field 'y |--> 2*y' """ a = '%s |--> %s' % (self.domain().variable_name(), self._im_gen) @@ -424,13 +423,13 @@ class FunctionFieldMorphism_polymod(FunctionFieldMorphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular - sage: f = L.hom(y*2); f # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field + sage: f = L.hom(y*2); f # optional - sage.libs.pari sage.rings.function_field Function Field endomorphism of Function field in y defined by y^3 + 6*x^3 + x Defn: y |--> 2*y - sage: factor(L.polynomial()) # optional - sage.libs.pari sage.libs.singular + sage: factor(L.polynomial()) # optional - sage.libs.pari sage.rings.function_field y^3 + 6*x^3 + x - sage: f(y).charpoly('y') # optional - sage.libs.pari sage.libs.singular + sage: f(y).charpoly('y') # optional - sage.libs.pari sage.rings.function_field y^3 + 6*x^3 + x """ def __init__(self, parent, im_gen, base_morphism): @@ -440,9 +439,9 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.libs.singular - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular - sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari sage.rings.function_field """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -459,10 +458,10 @@ def _call_(self, x): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari sage.libs.singular - sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field + sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari sage.rings.function_field 2/x*y + x^2/(x + 1) - sage: f(y) # optional - sage.libs.pari sage.libs.singular + sage: f(y) # optional - sage.libs.pari sage.rings.function_field 2*y """ v = x.list() @@ -718,34 +717,34 @@ class FunctionFieldCompletion(Map): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m # optional - sage.libs.pari sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x) # optional - sage.libs.pari + sage: m(x) # optional - sage.libs.pari sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) - sage: m(y) # optional - sage.libs.pari + sage: m(y) # optional - sage.libs.pari sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) - sage: m(x*y) == m(x) * m(y) # optional - sage.libs.pari + sage: m(x*y) == m(x) * m(y) # optional - sage.libs.pari sage.rings.function_field True - sage: m(x+y) == m(x) + m(y) # optional - sage.libs.pari + sage: m(x+y) == m(x) + m(y) # optional - sage.libs.pari sage.rings.function_field True The variable name of the series can be supplied. If the place is not rational such that the residue field is a proper extension of the constant field, you can also specify the generator name of the extension:: - sage: p2 = L.places_finite(2)[0] # optional - sage.libs.pari - sage: p2 # optional - sage.libs.pari + sage: p2 = L.places_finite(2)[0] # optional - sage.libs.pari sage.rings.function_field + sage: p2 # optional - sage.libs.pari sage.rings.function_field Place (x^2 + x + 1, x*y + 1) - sage: m2 = L.completion(p2, 't', gen_name='b') # optional - sage.libs.pari - sage: m2(x) # optional - sage.libs.pari + sage: m2 = L.completion(p2, 't', gen_name='b') # optional - sage.libs.pari sage.rings.function_field + sage: m2(x) # optional - sage.libs.pari sage.rings.function_field (b + 1) + t + t^2 + t^4 + t^8 + t^16 + O(t^20) - sage: m2(y) # optional - sage.libs.pari + sage: m2(y) # optional - sage.libs.pari sage.rings.function_field b + b*t + b*t^3 + b*t^4 + (b + 1)*t^5 + (b + 1)*t^7 + b*t^9 + b*t^11 + b*t^12 + b*t^13 + b*t^15 + b*t^16 + (b + 1)*t^17 + (b + 1)*t^19 + O(t^20) """ @@ -756,10 +755,10 @@ def __init__(self, field, place, name=None, prec=None, gen_name=None): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m # optional - sage.libs.pari sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -794,10 +793,10 @@ def _repr_type(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m # indirect doctest # optional - sage.libs.pari sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -811,10 +810,10 @@ def _call_(self, f): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m(y) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m(y) # optional - sage.libs.pari sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) """ if self._precision == infinity: @@ -829,10 +828,10 @@ def _call_with_args(self, f, args, kwds): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m(x+y, 10) # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m(x+y, 10) # indirect doctest # optional - sage.libs.pari sage.rings.function_field s^-1 + 1 + s^2 + s^4 + s^8 + O(s^9) """ if self._precision == infinity: @@ -853,10 +852,10 @@ def _expand(self, f, prec=None): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m(x, prec=20) # indirect doctest # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m(x, prec=20) # indirect doctest # optional - sage.libs.pari sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) """ @@ -887,14 +886,14 @@ def _expand_lazy(self, f): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p, prec=infinity) # optional - sage.libs.pari - sage: e = m(x); e # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p, prec=infinity) # optional - sage.libs.pari sage.rings.function_field + sage: e = m(x); e # optional - sage.libs.pari sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + ... - sage: e.coefficient(99) # indirect doctest # optional - sage.libs.pari + sage: e.coefficient(99) # indirect doctest # optional - sage.libs.pari sage.rings.function_field 0 - sage: e.coefficient(100) # optional - sage.libs.pari + sage: e.coefficient(100) # optional - sage.libs.pari sage.rings.function_field 1 """ place = self._place @@ -919,10 +918,10 @@ def default_precision(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: m = L.completion(p) # optional - sage.libs.pari - sage: m.default_precision() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field + sage: m.default_precision() # optional - sage.libs.pari sage.rings.function_field 20 """ return self._precision @@ -939,13 +938,13 @@ def _repr_(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: R = p.valuation_ring() # optional - sage.libs.pari - sage: k, fr_k, to_k = R.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: R = p.valuation_ring() # optional - sage.libs.pari sage.rings.function_field + sage: k, fr_k, to_k = R.residue_field() # optional - sage.libs.pari sage.rings.function_field + sage: k # optional - sage.libs.pari sage.rings.function_field Finite Field of size 2 - sage: fr_k # optional - sage.libs.pari + sage: fr_k # optional - sage.libs.pari sage.rings.function_field Ring morphism: From: Finite Field of size 2 To: Valuation ring at Place (x, x*y) @@ -967,12 +966,12 @@ def _repr_(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x-2) # optional - sage.libs.pari - sage: D = I.divisor() # optional - sage.libs.pari - sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari - sage: from_V # optional - sage.libs.pari + sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x - 2) # optional - sage.libs.pari sage.rings.function_field + sage: D = I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari sage.rings.function_field + sage: from_V # optional - sage.libs.pari sage.rings.function_field Linear map: From: Vector space of dimension 2 over Finite Field of size 5 To: Function field in y defined by y^2 + 4*x^3 + 4 @@ -994,12 +993,12 @@ def _repr_(self) -> str: EXAMPLES:: sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x-2) # optional - sage.libs.pari - sage: D = I.divisor() # optional - sage.libs.pari - sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari - sage: to_V # optional - sage.libs.pari + sage: F. = K.extension(t^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x - 2) # optional - sage.libs.pari sage.rings.function_field + sage: D = I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari sage.rings.function_field + sage: to_V # optional - sage.libs.pari sage.rings.function_field Section of linear map: From: Function field in y defined by y^2 + 4*x^3 + 4 To: Vector space of dimension 2 over Finite Field of size 5 diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index 179499ea9de..d0ccca9f1d2 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -31,11 +31,11 @@ orders such as equation orders:: sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - y - x) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: 1/y in O # optional - sage.libs.pari + sage: L. = K.extension(y^3 - y - x) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: 1/y in O # optional - sage.libs.pari sage.rings.function_field False - sage: x/y in O # optional - sage.libs.pari + sage: x/y in O # optional - sage.libs.pari sage.rings.function_field True Sage provides an extensive functionality for computations in maximal orders of @@ -44,25 +44,25 @@ sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: o = K.maximal_order() # optional - sage.libs.pari - sage: p = o.ideal(x+1) # optional - sage.libs.pari + sage: p = o.ideal(x + 1) # optional - sage.libs.pari sage: p.is_prime() # optional - sage.libs.pari True - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O.decomposition(p) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.decomposition(p) # optional - sage.libs.pari sage.rings.function_field [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - sage: p1, relative_degree,ramification_index = O.decomposition(p)[1] # optional - sage.libs.pari - sage: p1.parent() # optional - sage.libs.pari + sage: p1, relative_degree,ramification_index = O.decomposition(p)[1] # optional - sage.libs.pari sage.rings.function_field + sage: p1.parent() # optional - sage.libs.pari sage.rings.function_field Monoid of ideals of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: relative_degree # optional - sage.libs.pari + sage: relative_degree # optional - sage.libs.pari sage.rings.function_field 2 - sage: ramification_index # optional - sage.libs.pari + sage: ramification_index # optional - sage.libs.pari sage.rings.function_field 1 When the base constant field is the algebraic field `\QQbar`, the only prime ideals @@ -70,9 +70,9 @@ sage: K. = FunctionField(QQbar) # optional - sage.rings.number_field sage: R. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(y^2 - (x^3-x^2)) # optional - sage.rings.number_field - sage: p = K.maximal_order().ideal(x) # optional - sage.rings.number_field - sage: L.maximal_order().decomposition(p) # optional - sage.rings.number_field + sage: L. = K.extension(y^2 - (x^3-x^2)) # optional - sage.rings.function_field sage.rings.number_field + sage: p = K.maximal_order().ideal(x) # optional - sage.rings.function_field sage.rings.number_field + sage: L.maximal_order().decomposition(p) # optional - sage.rings.function_field sage.rings.number_field [(Ideal (1/x*y - I) of Maximal order of Function field in y defined by y^2 - x^3 + x^2, 1, 1), @@ -278,8 +278,8 @@ def _repr_(self): Maximal infinite order of Rational function field in y over Rational Field sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage.rings.function_field + sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules sage.rings.function_field Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return "Maximal infinite order of %s"%(self.function_field(),) diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index 22cc02e9af0..586c2348943 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -31,8 +31,8 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field Order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under @@ -40,10 +40,10 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.singular - sage: y.is_integral() # optional - sage.libs.singular + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.rings.function_field + sage: y.is_integral() # optional - sage.rings.function_field False - sage: L.order(y) # optional - sage.libs.singular + sage: L.order(y) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, y^2, y^3, y^4) must be closed under multiplication @@ -52,11 +52,11 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: L.order(L(x)) # optional - sage.libs.singular + sage: L.order(L(x)) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: basis (1, x, x^2, x^3, x^4) is not linearly independent - sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.libs.singular + sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: basis (y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x) is not linearly independent @@ -68,9 +68,9 @@ def __init__(self, basis, check=True): TESTS:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(O).run() # optional - sage.libs.pari sage.rings.function_field """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -153,12 +153,12 @@ def ideal_with_gens_over_base(self, gens): We construct some ideals in a nontrivial function field:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari + sage: I.module() # optional - sage.libs.pari sage.rings.function_field Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -168,13 +168,13 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.rings.function_field Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari + sage: y in I # optional - sage.libs.pari sage.rings.function_field True - sage: y^2 in I # optional - sage.libs.pari + sage: y^2 in I # optional - sage.libs.pari sage.rings.function_field False """ F = self.function_field() @@ -210,13 +210,13 @@ def ideal(self, *gens): sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari sage: O = K.maximal_order() # optional - sage.libs.pari sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: S = L.equation_order() # optional - sage.libs.pari - sage: S.ideal(1/y) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: S = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: S.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari + sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari sage.rings.function_field Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari + sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.rings.function_field True """ if len(gens) == 1: @@ -237,9 +237,9 @@ def polynomial(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.polynomial() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.polynomial() # optional - sage.libs.pari sage.rings.function_field y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -251,9 +251,9 @@ def basis(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.basis() # optional - sage.libs.pari sage.rings.function_field (1, y, y^2, y^3) """ return self._basis @@ -266,9 +266,9 @@ def free_module(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.free_module() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.free_module() # optional - sage.libs.pari sage.rings.function_field Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -290,10 +290,10 @@ def coordinate_vector(self, e): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: f = (x + y)^3 # optional - sage.libs.pari - sage: O.coordinate_vector(f) # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: f = (x + y)^3 # optional - sage.libs.pari sage.rings.function_field + sage: O.coordinate_vector(f) # optional - sage.libs.pari sage.rings.function_field (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e), check=False) @@ -313,15 +313,15 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari sage.rings.function_field Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under multiplication and contains the identity element (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari sage.rings.function_field Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication @@ -330,7 +330,7 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari sage.rings.function_field Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -338,9 +338,9 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): Note that 1 does not need to be an element of the basis, as long as it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari + sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari sage.rings.function_field Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - sage: O.basis() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari sage.rings.function_field (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) """ def __init__(self, basis, check=True): @@ -350,9 +350,9 @@ def __init__(self, basis, check=True): TESTS:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order_infinite() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order_infinite() # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(O).run() # optional - sage.libs.pari sage.rings.function_field """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -443,12 +443,12 @@ def ideal_with_gens_over_base(self, gens): We construct some ideals in a nontrivial function field:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order(); O # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari + sage: I.module() # optional - sage.libs.pari sage.rings.function_field Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] @@ -457,13 +457,13 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.rings.function_field Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari + sage: y in I # optional - sage.libs.pari sage.rings.function_field True - sage: y^2 in I # optional - sage.libs.pari + sage: y^2 in I # optional - sage.libs.pari sage.rings.function_field False """ F = self.function_field() @@ -498,9 +498,9 @@ def ideal(self, *gens): sage: K. = FunctionField(QQ); R. = K[] sage: O = K.maximal_order_infinite() - sage: I = O.ideal(x^2-4) - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) # optional - sage.libs.singular + sage: I = O.ideal(x^2 - 4) + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: S = L.order_infinite_with_basis([1, 1/x^2*y]) # optional - sage.rings.function_field """ if len(gens) == 1: gens = gens[0] @@ -520,9 +520,9 @@ def polynomial(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.polynomial() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.polynomial() # optional - sage.libs.pari sage.rings.function_field y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -534,9 +534,9 @@ def basis(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.basis() # optional - sage.libs.pari sage.rings.function_field (1, y, y^2, y^3) """ return self._basis @@ -549,9 +549,9 @@ def free_module(self): EXAMPLES:: sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.free_module() # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field + sage: O.free_module() # optional - sage.libs.pari sage.rings.function_field Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index ff5a7ae82a2..2b162c01d19 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.rings.function_field + r""" Orders of function fields - polymod implementation """ @@ -35,10 +37,10 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari """ FunctionFieldMaximalOrder.__init__(self, field, ideal_class) @@ -130,26 +132,26 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] - sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) - sage: O = L.maximal_order() - sage: y in O + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: y in O # optional - sage.libs.pari True - sage: 1/y in O + sage: 1/y in O # optional - sage.libs.pari False - sage: x in O + sage: x in O # optional - sage.libs.pari True - sage: 1/x in O + sage: 1/x in O # optional - sage.libs.pari False - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: O = L.maximal_order() - sage: 1 in O + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: 1 in O # optional - sage.libs.pari True - sage: y in O + sage: y in O # optional - sage.libs.pari False - sage: x*y in O + sage: x*y in O # optional - sage.libs.pari True - sage: x^2*y in O + sage: x^2*y in O # optional - sage.libs.pari True """ F = self.function_field() @@ -172,13 +174,13 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order(); O + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order(); O # optional - sage.libs.pari Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() + sage: I.module() # optional - sage.libs.pari Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -187,14 +189,14 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.equation_order() - sage: I = O.ideal_with_gens_over_base([y]); I + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I + sage: y in I # optional - sage.libs.pari True - sage: y^2 in I + sage: y^2 in I # optional - sage.libs.pari False """ return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) @@ -210,16 +212,16 @@ def _ideal_from_vectors(self, vecs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: v1 = O.coordinate_vector(x^3+1) - sage: v2 = O.coordinate_vector(y) - sage: v1 + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: v1 = O.coordinate_vector(x^3 + 1) # optional - sage.libs.pari + sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari + sage: v1 # optional - sage.libs.pari (x^3 + 1, 0) - sage: v2 + sage: v2 # optional - sage.libs.pari (0, 1) - sage: O._ideal_from_vectors([v1,v2]) + sage: O._ideal_from_vectors([v1, v2]) # optional - sage.libs.pari Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -243,18 +245,18 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) - sage: O = L.maximal_order() - sage: I = O.ideal(y^2) - sage: m = I.basis_matrix() - sage: v1 = m[0] - sage: v2 = m[1] - sage: v1 + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(y^2) # optional - sage.libs.pari + sage: m = I.basis_matrix() # optional - sage.libs.pari + sage: v1 = m[0] # optional - sage.libs.pari + sage: v2 = m[1] # optional - sage.libs.pari + sage: v1 # optional - sage.libs.pari (x^3 + 1, 0) - sage: v2 + sage: v2 # optional - sage.libs.pari (0, x^3 + 1) - sage: O._ideal_from_vectors([v1,v2]) # indirect doctest + sage: O._ideal_from_vectors([v1, v2]) # indirect doctest # optional - sage.libs.pari Ideal (x^3 + 1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -307,17 +309,17 @@ def ideal(self, *gens, **kwargs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: O = K.maximal_order() - sage: I = O.ideal(x^2 - 4) - sage: L. = K.extension(y^2 - x^3 - 1) - sage: S = L.maximal_order() - sage: S.ideal(1/y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: O = K.maximal_order() # optional - sage.libs.pari + sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari + sage: S = L.maximal_order() # optional - sage.libs.pari + sage: S.ideal(1/y) # optional - sage.libs.pari Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2 - 4); I2 + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) + sage: I2 == S.ideal(I) # optional - sage.libs.pari True sage: K. = FunctionField(QQ); R. = K[] @@ -350,10 +352,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.polynomial() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.polynomial() # optional - sage.libs.pari y^4 + x*y + 4*x + 1 sage: K. = FunctionField(QQ); R. = K[] @@ -371,10 +373,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.equation_order() - sage: O.basis() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.equation_order() # optional - sage.libs.pari + sage: O.basis() # optional - sage.libs.pari (1, y, y^2, y^3) sage: K. = FunctionField(QQ) @@ -394,16 +396,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: O = L.maximal_order() - sage: O.gen() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.gen() # optional - sage.libs.pari 1 - sage: O.gen(1) + sage: O.gen(1) # optional - sage.libs.pari y - sage: O.gen(2) + sage: O.gen(2) # optional - sage.libs.pari (1/(x^3 + x^2 + x))*y^2 - sage: O.gen(3) + sage: O.gen(3) # optional - sage.libs.pari Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -419,10 +421,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order() - sage: Oinf.ngens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order() # optional - sage.libs.pari + sage: Oinf.ngens() # optional - sage.libs.pari 3 """ return len(self._basis) @@ -433,11 +435,12 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.free_module() - Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.free_module() # optional - sage.libs.pari + Free module of degree 4 and rank 4 over + Maximal order of Rational function field in x over Finite Field of size 7 User basis matrix: [1 0 0 0] [0 1 0 0] @@ -452,12 +455,12 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.coordinate_vector(y) + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.coordinate_vector(y) # optional - sage.libs.pari (0, 1, 0, 0) - sage: O.coordinate_vector(x*y) + sage: O.coordinate_vector(x*y) # optional - sage.libs.pari (0, x, 0, 0) sage: K. = FunctionField(QQ); R. = K[] @@ -500,10 +503,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.different() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.different() # optional - sage.libs.pari Ideal (y^3 + 2*x) of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -516,10 +519,10 @@ def codifferent(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O.codifferent() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O.codifferent() # optional - sage.libs.pari Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y @@ -536,10 +539,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: O._codifferent_matrix() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: O._codifferent_matrix() # optional - sage.libs.pari [ 4 0 0 4*x] [ 0 0 4*x 5*x + 3] [ 0 4*x 5*x + 3 0] @@ -567,12 +570,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x + 1) - sage: O.decomposition(p) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = o.ideal(x + 1) # optional - sage.libs.pari + sage: O.decomposition(p) # optional - sage.libs.pari [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -695,14 +698,14 @@ class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinit EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) - sage: F.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: F.maximal_order_infinite() # optional - sage.libs.pari Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: L.maximal_order_infinite() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: L.maximal_order_infinite() # optional - sage.libs.pari Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ def __init__(self, field, category=None): @@ -711,10 +714,10 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) - sage: O = F.maximal_order_infinite() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari + sage: O = F.maximal_order_infinite() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari """ FunctionFieldMaximalOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) @@ -735,18 +738,18 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.basis() # optional - sage.libs.pari (1, 1/x*y) - sage: 1 in Oinf + sage: 1 in Oinf # optional - sage.libs.pari True - sage: 1/x*y in Oinf + sage: 1/x*y in Oinf # optional - sage.libs.pari True - sage: x*y in Oinf + sage: x*y in Oinf # optional - sage.libs.pari False - sage: 1/x in Oinf + sage: 1/x in Oinf # optional - sage.libs.pari True """ F = self.function_field() @@ -770,18 +773,18 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.basis() # optional - sage.libs.pari (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.basis() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.basis() # optional - sage.libs.pari (1, 1/x*y) """ return self._basis @@ -794,16 +797,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.gen() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.gen() # optional - sage.libs.pari 1 - sage: Oinf.gen(1) + sage: Oinf.gen(1) # optional - sage.libs.pari 1/x^2*y - sage: Oinf.gen(2) + sage: Oinf.gen(2) # optional - sage.libs.pari (1/(x^4 + x^3 + x^2))*y^2 - sage: Oinf.gen(3) + sage: Oinf.gen(3) # optional - sage.libs.pari Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -819,10 +822,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.ngens() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.ngens() # optional - sage.libs.pari 3 """ return len(self._basis) @@ -837,20 +840,21 @@ def ideal(self, *gens): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: I = Oinf.ideal(x,y); I + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x, y); I # optional - sage.libs.pari Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(x,y); I - Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(x, y); I # optional - sage.libs.pari + Ideal (x) of Maximal infinite order of Function field + in y defined by y^2 + y + (x^2 + 1)/x """ if len(gens) == 1: gens = gens[0] @@ -937,11 +941,11 @@ def _to_iF(self, I): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: I = Oinf.ideal(y) - sage: Oinf._to_iF(I) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: I = Oinf.ideal(y) # optional - sage.libs.pari + sage: Oinf._to_iF(I) # optional - sage.libs.pari Ideal (1, 1/x*s) of Maximal order of Function field in s defined by s^2 + x*s + x^3 + x """ @@ -958,10 +962,10 @@ def decomposition(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: Oinf = F.maximal_order_infinite() - sage: Oinf.decomposition() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.decomposition() # optional - sage.libs.pari [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -969,10 +973,10 @@ def decomposition(self): :: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.decomposition() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.decomposition() # optional - sage.libs.pari [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] @@ -1016,10 +1020,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf.different() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf.different() # optional - sage.libs.pari Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1037,10 +1041,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: Oinf._codifferent_matrix() + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: Oinf._codifferent_matrix() # optional - sage.libs.pari [ 0 1/x] [ 1/x 1/x^2] """ @@ -1068,13 +1072,13 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: L. = K.extension(Y^2 + Y + x + 1/x) - sage: Oinf = L.maximal_order_infinite() - sage: f = 1/y^2 - sage: f in Oinf + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari + sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari + sage: f = 1/y^2 # optional - sage.libs.pari + sage: f in Oinf # optional - sage.libs.pari True - sage: Oinf.coordinate_vector(f) + sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) """ return self._module.coordinate_vector(self._to_module(e)) @@ -1090,9 +1094,9 @@ class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: L.maximal_order() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: L.maximal_order() # optional - sage.libs.pari Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1102,10 +1106,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] - sage: L. = K.extension(y^4 + x*y + 4*x + 1) - sage: O = L.maximal_order() - sage: TestSuite(O).run() + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari + sage: O = L.maximal_order() # optional - sage.libs.pari + sage: TestSuite(O).run() # optional - sage.libs.pari """ FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) @@ -1123,12 +1127,12 @@ def p_radical(self, prime): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] - sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x + 1) - sage: O.p_radical(p) + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = o.ideal(x + 1) # optional - sage.libs.pari + sage: O.p_radical(p) # optional - sage.libs.pari Ideal (x + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -1185,12 +1189,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) - sage: o = K.maximal_order() - sage: O = F.maximal_order() - sage: p = o.ideal(x + 1) - sage: O.decomposition(p) + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari + sage: o = K.maximal_order() # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari + sage: p = o.ideal(x + 1) # optional - sage.libs.pari + sage: O.decomposition(p) # optional - sage.libs.pari [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index c9a045e2bb3..add36705671 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -95,9 +95,9 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.singular - sage: O = L.equation_order() # optional - sage.libs.singular - sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.function_field + sage: O.ideal_with_gens_over_base([x^3 + 1, -y]) # optional - sage.rings.function_field Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1 """ return self.ideal(gens) @@ -387,11 +387,11 @@ def ideal(self, *gens): sage: O = K.maximal_order() sage: O.ideal(x) Ideal (x) of Maximal order of Rational function field in x over Rational Field - sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list + sage: O.ideal([x, 1/x]) == O.ideal(x, 1/x) # multiple generators may be given as a list True - sage: O.ideal(x^3+1,x^3+6) + sage: O.ideal(x^3 + 1, x^3 + 6) Ideal (1) of Maximal order of Rational function field in x over Rational Field - sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I + sage: I = O.ideal((x^2+1)*(x^3+1), (x^3+6)*(x^2+1)); I Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field sage: O.ideal(I) Ideal (x^2 + 1) of Maximal order of Rational function field in x over Rational Field @@ -540,11 +540,11 @@ def ideal(self, *gens): sage: O = K.maximal_order_infinite() sage: O.ideal(x) Ideal (x) of Maximal infinite order of Rational function field in x over Rational Field - sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list + sage: O.ideal([x, 1/x]) == O.ideal(x ,1/x) # multiple generators may be given as a list True - sage: O.ideal(x^3+1,x^3+6) + sage: O.ideal(x^3 + 1, x^3 + 6) Ideal (x^3) of Maximal infinite order of Rational function field in x over Rational Field - sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I + sage: I = O.ideal((x^2+1)*(x^3+1), (x^3+6)*(x^2+1)); I Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field sage: O.ideal(I) Ideal (x^5) of Maximal infinite order of Rational function field in x over Rational Field diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 8458ff77f67..f343243261e 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -12,8 +12,8 @@ All rational places of a function field can be computed:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: L.places() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: L.places() # optional - sage.libs.pari sage.rings.function_field [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y)] @@ -76,8 +76,8 @@ class FunctionFieldPlace(Element): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: L.places_finite()[0] # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field Place (x, y) """ def __init__(self, parent, prime): @@ -87,9 +87,9 @@ def __init__(self, parent, prime): TESTS:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: TestSuite(p).run() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(p).run() # optional - sage.libs.pari sage.rings.function_field """ Element.__init__(self, parent) @@ -102,9 +102,9 @@ def __hash__(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: {p: 1} # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: {p: 1} # optional - sage.libs.pari sage.rings.function_field {Place (x, y): 1} """ return hash((self.function_field(), self._prime)) @@ -116,9 +116,9 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: p # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: p # optional - sage.libs.pari sage.rings.function_field Place (x, y) """ try: @@ -135,9 +135,9 @@ def _latex_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: latex(p) # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: latex(p) # optional - sage.libs.pari sage.rings.function_field \left(y\right) """ return self._prime._latex_() @@ -149,13 +149,13 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari - sage: p1 < p2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field + sage: p1 < p2 # optional - sage.libs.pari sage.rings.function_field True - sage: p2 < p1 # optional - sage.libs.pari + sage: p2 < p1 # optional - sage.libs.pari sage.rings.function_field False - sage: p1 == p3 # optional - sage.libs.pari + sage: p1 == p3 # optional - sage.libs.pari sage.rings.function_field False """ from sage.rings.function_field.order import FunctionFieldOrderInfinite @@ -176,10 +176,10 @@ def _acted_upon_(self, other, self_on_left): sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari - sage: P = I.place() # optional - sage.libs.pari - sage: -3*P + 5*P # optional - sage.libs.pari + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari sage.rings.function_field + sage: P = I.place() # optional - sage.libs.pari sage.rings.function_field + sage: -3*P + 5*P # optional - sage.libs.pari sage.rings.function_field 2*Place (x + 1, y) """ if self_on_left: @@ -193,9 +193,9 @@ def _neg_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari - sage: -p1 + p2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field + sage: -p1 + p2 # optional - sage.libs.pari sage.rings.function_field - Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -209,9 +209,9 @@ def _add_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari - sage: p1 + p2 + p3 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field + sage: p1 + p2 + p3 # optional - sage.libs.pari sage.rings.function_field Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) + Place (x, y) @@ -226,9 +226,9 @@ def _sub_(self, other): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p1, p2 = L.places()[:2] # optional - sage.libs.pari - sage: p1 - p2 # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p1, p2 = L.places()[:2] # optional - sage.libs.pari sage.rings.function_field + sage: p1 - p2 # optional - sage.libs.pari sage.rings.function_field Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -271,9 +271,9 @@ def function_field(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p = L.places()[0] # optional - sage.libs.pari - sage: p.function_field() == L # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places()[0] # optional - sage.libs.pari sage.rings.function_field + sage: p.function_field() == L # optional - sage.libs.pari sage.rings.function_field True """ return self.parent()._field @@ -285,9 +285,9 @@ def prime_ideal(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: p = L.places()[0] # optional - sage.libs.pari - sage: p.prime_ideal() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: p = L.places()[0] # optional - sage.libs.pari sage.rings.function_field + sage: p.prime_ideal() # optional - sage.libs.pari sage.rings.function_field Ideal (1/x^3*y^2 + 1/x) of Maximal infinite order of Function field in y defined by y^3 + x^3*y + x """ @@ -300,11 +300,11 @@ def divisor(self, multiplicity=1): EXAMPLES:: sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + 1,y) # optional - sage.libs.pari - sage: P = I.place() # optional - sage.libs.pari - sage: P.divisor() # optional - sage.libs.pari + sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x + 1,y) # optional - sage.libs.pari sage.rings.function_field + sage: P = I.place() # optional - sage.libs.pari sage.rings.function_field + sage: P.divisor() # optional - sage.libs.pari sage.rings.function_field Place (x + 1, y) """ from .divisor import prime_divisor @@ -322,8 +322,8 @@ class PlaceSet(UniqueRepresentation, Parent): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: L.place_set() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field Set of places of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldPlace @@ -335,9 +335,9 @@ def __init__(self, field): TESTS:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: places = L.place_set() # optional - sage.libs.pari - sage: TestSuite(places).run() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(places).run() # optional - sage.libs.pari sage.rings.function_field """ self.Element = field._place_class Parent.__init__(self, category = Sets().Infinite()) @@ -351,8 +351,8 @@ def _repr_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: L.place_set() # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field Set of places of Function field in y defined by y^3 + x^3*y + x """ return "Set of places of {}".format(self._field) @@ -364,10 +364,10 @@ def _element_constructor_(self, x): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: places = L.place_set() # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: places(O.ideal(x,y)) # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field + sage: places(O.ideal(x, y)) # optional - sage.libs.pari sage.rings.function_field Place (x, y) """ from .ideal import FunctionFieldIdeal @@ -384,9 +384,9 @@ def _an_element_(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: places = L.place_set() # optional - sage.libs.pari - sage: places.an_element() # random # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: places.an_element() # random # optional - sage.libs.pari sage.rings.function_field Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 """ @@ -407,9 +407,9 @@ def function_field(self): EXAMPLES:: sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: PS = L.place_set() # optional - sage.libs.pari - sage: PS.function_field() == L # optional - sage.libs.pari + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field + sage: PS = L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: PS.function_field() == L # optional - sage.libs.pari sage.rings.function_field True """ return self._field diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index c7781a975f9..362ce0c9f62 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.function_field #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee @@ -278,8 +279,8 @@ def _gaps_wronskian(self): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari - sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari + sage: p = O.ideal(x, y).place() # optional - sage.libs.pari + sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari [1, 2, 4] sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari @@ -401,10 +402,10 @@ def _residue_field(self, name=None): :: sage: K. = FunctionField(QQ); _. = K[] - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular + sage: L. = K.extension(Y^3 + Y - x^4) sage: O = K.maximal_order() sage: I = O.ideal(x) - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular + sage: [p.residue_field() for p in L.places_above(I.place())] [(Rational Field, Ring morphism: From: Rational Field To: Valuation ring at Place (x, y, y^2), Ring morphism: @@ -415,7 +416,7 @@ def _residue_field(self, name=None): To: Valuation ring at Place (x, x*y, y^2 + 1), Ring morphism: From: Valuation ring at Place (x, x*y, y^2 + 1) To: Number Field in s with defining polynomial x^2 - 2*x + 2)] - sage: for p in L.places_above(I.place()): # optional - sage.libs.singular + sage: for p in L.places_above(I.place()): ....: k, fr_k, to_k = p.residue_field() ....: assert all(fr_k(k(e)) == e for e in range(10)) ....: assert all(to_k(fr_k(e)) == e for e in [k.random_element() for i in [1..10]]) @@ -423,10 +424,10 @@ def _residue_field(self, name=None): :: sage: K. = FunctionField(QQbar); _. = K[] # optional - sage.rings.number_field - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.singular sage.rings.number_field - sage: O = K.maximal_order() # optional - sage.libs.singular sage.rings.number_field - sage: I = O.ideal(x) # optional - sage.libs.singular sage.rings.number_field - sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.libs.singular sage.rings.number_field + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: I = O.ideal(x) # optional - sage.rings.number_field + sage: [p.residue_field() for p in L.places_above(I.place())] # optional - sage.rings.number_field [(Algebraic Field, Ring morphism: From: Algebraic Field To: Valuation ring at Place (x, y - I, y^2 + 1), Ring morphism: diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py index 760c44d846e..df0ad509c9c 100644 --- a/src/sage/rings/function_field/place_rational.py +++ b/src/sage/rings/function_field/place_rational.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee @@ -21,11 +22,11 @@ def degree(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: p = i.place() # optional - sage.libs.pari - sage: p.degree() # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) + sage: O = F.maximal_order() + sage: i = O.ideal(x^2 + x + 1) + sage: p = i.place() + sage: p.degree() 2 """ if self.is_infinite_place(): @@ -39,10 +40,10 @@ def is_infinite_place(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) + sage: F.places() [Place (1/x), Place (x), Place (x + 1)] - sage: [p.is_infinite_place() for p in F.places()] # optional - sage.libs.pari + sage: [p.is_infinite_place() for p in F.places()] [True, False, False] """ F = self.function_field() @@ -54,10 +55,10 @@ def local_uniformizer(self): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) + sage: F.places() [Place (1/x), Place (x), Place (x + 1)] - sage: [p.local_uniformizer() for p in F.places()] # optional - sage.libs.pari + sage: [p.local_uniformizer() for p in F.places()] [1/x, x, x + 1] """ return self.prime_ideal().gen() @@ -68,17 +69,17 @@ def residue_field(self, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari - sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) + sage: O = F.maximal_order() + sage: p = O.ideal(x^2 + x + 1).place() + sage: k, fr_k, to_k = p.residue_field() + sage: k Finite Field in z2 of size 2^2 - sage: fr_k # optional - sage.libs.pari + sage: fr_k Ring morphism: From: Finite Field in z2 of size 2^2 To: Valuation ring at Place (x^2 + x + 1) - sage: to_k # optional - sage.libs.pari + sage: to_k Ring morphism: From: Valuation ring at Place (x^2 + x + 1) To: Finite Field in z2 of size 2^2 @@ -96,16 +97,16 @@ def _residue_field(self, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: p = i.place() # optional - sage.libs.pari - sage: R, fr, to = p._residue_field() # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) + sage: O = F.maximal_order() + sage: i = O.ideal(x^2 + x + 1) + sage: p = i.place() + sage: R, fr, to = p._residue_field() + sage: R Finite Field in z2 of size 2^2 - sage: [fr(e) for e in R.list()] # optional - sage.libs.pari + sage: [fr(e) for e in R.list()] [0, x, x + 1, 1] - sage: to(x*(x+1)) == to(x) * to(x+1) # optional - sage.libs.pari + sage: to(x*(x+1)) == to(x) * to(x+1) True """ F = self.function_field() @@ -162,10 +163,10 @@ def valuation_ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: p.valuation_ring() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^2 + Y + x + 1/x) + sage: p = L.places_finite()[0] + sage: p.valuation_ring() Valuation ring at Place (x, x*y) """ from .valuation_ring import FunctionFieldValuationRing diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py index 99ca4b76e29..420f47a43e3 100644 --- a/src/sage/rings/function_field/valuation.py +++ b/src/sage/rings/function_field/valuation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Discrete valuations on function fields @@ -33,8 +32,8 @@ sage: v = K.valuation(x - 1); v (x - 1)-adic valuation sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: w = v.extensions(L); w # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: w = v.extensions(L); w # optional - sage.rings.function_field [[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation, [ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation] @@ -57,9 +56,9 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(x - 1) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: ws = v.extensions(L) # optional - sage.libs.singular - sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: ws = v.extensions(L) # optional - sage.rings.function_field + sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # optional - sage.rings.function_field Run test suite for valuations that do not correspond to a classical place:: @@ -88,9 +87,9 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(1/x) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular - sage: w = v.extensions(L) # optional - sage.libs.singular - sage: TestSuite(w).run() # long time # optional - sage.libs.singular + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.rings.function_field + sage: w = v.extensions(L) # optional - sage.rings.function_field + sage: TestSuite(w).run() # long time # optional - sage.rings.function_field Run test suite for a valuation with `v(1/x) > 0` which does not come from a classical valuation of the infinite place:: @@ -107,7 +106,7 @@ sage: K. = FunctionField(QQ) sage: v = K.valuation(x^2 + 1) sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: ws = v.extensions(L) # optional - sage.libs.singular + sage: ws = v.extensions(L) # optional - sage.rings.function_field sage: for w in ws: TestSuite(w).run(max_runs=100) # long time Run test suite for a finite place with residual degree and ramification:: @@ -123,8 +122,8 @@ sage: R. = K[] sage: L. = K.extension(y^2 - (x^2 + x + 1)) sage: v = K.valuation(x - 1) - sage: w = v.extension(L) # optional - sage.libs.singular - sage: TestSuite(w).run() # long time # optional - sage.libs.singular + sage: w = v.extension(L) # optional - sage.rings.function_field + sage: TestSuite(w).run() # long time # optional - sage.rings.function_field Run test suite for a valuation which sends an element to `-\infty`:: @@ -172,7 +171,7 @@ class FunctionFieldValuationFactory(UniqueFactory): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(1); v # indirect doctest + sage: v = K.valuation(1); v # indirect doctest (x - 1)-adic valuation sage: v(x) 0 @@ -193,7 +192,7 @@ def create_key_and_extra_args(self, domain, prime): get the same object:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(x - 1) # indirect doctest + sage: v = K.valuation(x - 1) # indirect doctest sage: R. = QQ[] sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) @@ -256,7 +255,7 @@ def create_key_and_extra_args_from_place(self, domain, generator): TESTS: sage: K. = FunctionField(QQ) - sage: v = K.valuation(1/x) # indirect doctest + sage: v = K.valuation(1/x) # indirect doctest """ if generator not in domain.base_field(): @@ -306,9 +305,9 @@ def create_key_and_extra_args_from_valuation(self, domain, valuation): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) # optional - sage.libs.singular - sage: v = K.valuation(x) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular + sage: L. = K.extension(y^3 + 1/x^3*y + 2/x^4) # optional - sage.rings.function_field + sage: v = K.valuation(x) # optional - sage.rings.function_field + sage: v.extensions(L) # optional - sage.rings.function_field [[ (x)-adic valuation, v(y) = 1 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y), [ (x)-adic valuation, v(y) = 1/2 ]-adic valuation (in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)] @@ -353,9 +352,9 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.libs.singular - sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.libs.singular - sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.rings.function_field + sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.rings.function_field """ from sage.categories.function_fields import FunctionFields @@ -400,7 +399,7 @@ def create_object(self, version, key, **extra_args): sage: K. = FunctionField(QQ) sage: R. = QQ[] sage: w = valuations.GaussValuation(R, QQ.valuation(2)) - sage: v = K.valuation(w); v # indirect doctest + sage: v = K.valuation(w); v # indirect doctest 2-adic valuation """ @@ -462,7 +461,7 @@ class FunctionFieldValuation_base(DiscretePseudoValuation): TESTS:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest + sage: v = K.valuation(x) # indirect doctest sage: from sage.rings.function_field.valuation import FunctionFieldValuation_base sage: isinstance(v, FunctionFieldValuation_base) True @@ -477,7 +476,7 @@ class DiscreteFunctionFieldValuation_base(DiscreteValuation): TESTS:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest + sage: v = K.valuation(x) # indirect doctest sage: from sage.rings.function_field.valuation import DiscreteFunctionFieldValuation_base sage: isinstance(v, DiscreteFunctionFieldValuation_base) True @@ -492,8 +491,8 @@ def extensions(self, L): sage: K. = FunctionField(QQ) sage: v = K.valuation(x) sage: R. = K[] - sage: L. = K.extension(y^2 - x) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: v.extensions(L) # optional - sage.rings.function_field [(x)-adic valuation] TESTS: @@ -502,8 +501,8 @@ def extensions(self, L): sage: v = K.valuation(1/x) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.libs.singular - sage: sorted(v.extensions(L), key=str) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - 1/(x^2 + 1)) # optional - sage.rings.function_field + sage: sorted(v.extensions(L), key=str) # optional - sage.rings.function_field [[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation, [ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation] @@ -511,12 +510,12 @@ def extensions(self, L): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari sage.rings.function_field + sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari sage.rings.function_field Traceback (most recent call last): ... NotImplementedError @@ -530,19 +529,19 @@ def extensions(self, L): sage: v = K.valuation(v) sage: R. = K[] - sage: L. = K.extension(y^3 - x^4 - 1) # optional - sage.libs.singular - sage: v.extensions(L) # optional - sage.libs.singular + sage: L. = K.extension(y^3 - x^4 - 1) # optional - sage.rings.function_field + sage: v.extensions(L) # optional - sage.rings.function_field [2-adic valuation] Test that this works in towers:: sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: L. = L.extension(z - y) # optional - sage.libs.pari - sage: v = K.valuation(x) # optional - sage.libs.pari - sage: v.extensions(L) # optional - sage.libs.pari + sage: L. = K.extension(y - x) # optional - sage.libs.pari sage.rings.function_field + sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field + sage: L. = L.extension(z - y) # optional - sage.libs.pari sage.rings.function_field + sage: v = K.valuation(x) # optional - sage.libs.pari sage.rings.function_field + sage: v.extensions(L) # optional - sage.libs.pari sage.rings.function_field [(x)-adic valuation] """ K = self.domain() @@ -601,7 +600,7 @@ def element_with_valuation(self, s): EXAMPLES:: - sage: K. = NumberField(x^3+6) # optional - sage.rings.number_field + sage: K. = NumberField(x^3 + 6) # optional - sage.rings.number_field sage: v = K.valuation(2) # optional - sage.rings.number_field sage: R. = K[] # optional - sage.rings.number_field sage: w = GaussValuation(R, v).augmentation(x, 1/123) # optional - sage.rings.number_field @@ -822,7 +821,7 @@ def extensions(self, L): sage: K. = FunctionField(QQ) sage: v = K.valuation(x^2 + 1) sage: L. = FunctionField(GaussianIntegers().fraction_field()) - sage: v.extensions(L) # indirect doctest + sage: v.extensions(L) # indirect doctest [(x - I)-adic valuation, (x + I)-adic valuation] """ @@ -854,7 +853,7 @@ def _call_(self, f): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(x) # indirect doctest + sage: v = K.valuation(x) # indirect doctest sage: v((x+1)/x^2) -2 @@ -1077,8 +1076,8 @@ def residue_ring(self): Rational function field in x over Finite Field of size 2 sage: R. = K[] - sage: L. = K.extension(y^2 + 2*x) # optional - sage.libs.singular - sage: w.extension(L).residue_ring() # optional - sage.libs.singular + sage: L. = K.extension(y^2 + 2*x) # optional - sage.rings.function_field + sage: w.extension(L).residue_ring() # optional - sage.rings.function_field Function field in u2 defined by u2^2 + x TESTS: @@ -1109,9 +1108,9 @@ class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, Discret sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L); w # optional - sage.libs.singular + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.rings.function_field + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.rings.function_field + sage: w = v.extension(L); w # optional - sage.rings.function_field (x - 1)-adic valuation """ @@ -1121,11 +1120,11 @@ def __init__(self, parent, approximant, G, approximants): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.rings.function_field + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.rings.function_field + sage: w = v.extension(L) # optional - sage.rings.function_field sage: from sage.rings.function_field.valuation import FunctionFieldFromLimitValuation - sage: isinstance(w, FunctionFieldFromLimitValuation) # optional - sage.libs.singular + sage: isinstance(w, FunctionFieldFromLimitValuation) # optional - sage.rings.function_field True """ @@ -1140,10 +1139,10 @@ def _to_base_domain(self, f): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular - sage: w._to_base_domain(y).parent() # optional - sage.libs.singular + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.rings.function_field + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.rings.function_field + sage: w = v.extension(L) # optional - sage.rings.function_field + sage: w._to_base_domain(y).parent() # optional - sage.rings.function_field Univariate Polynomial Ring in y over Rational function field in x over Rational Field """ @@ -1157,10 +1156,10 @@ def scale(self, scalar): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.libs.singular - sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.libs.singular - sage: w = v.extension(L) # optional - sage.libs.singular - sage: 3*w # optional - sage.libs.singular + sage: L. = K.extension(y^2 - (x^2 + x + 1)) # optional - sage.rings.function_field + sage: v = K.valuation(x - 1) # indirect doctest # optional - sage.rings.function_field + sage: w = v.extension(L) # optional - sage.rings.function_field + sage: 3*w # optional - sage.rings.function_field 3 * (x - 1)-adic valuation """ @@ -1206,10 +1205,10 @@ def _to_base_domain(self, f): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w._to_base_domain(y) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: w._to_base_domain(y) # optional - sage.libs.pari sage.rings.function_field x^2*y """ @@ -1223,10 +1222,10 @@ def _from_base_domain(self, f): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari sage.rings.function_field y r""" @@ -1240,10 +1239,10 @@ def scale(self, scalar): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: 3*w # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: 3*w # optional - sage.libs.pari sage.rings.function_field 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) """ @@ -1260,9 +1259,9 @@ def _repr_(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: v.extension(L) # indirect doctest # optional - sage.libs.pari + sage: v.extension(L) # indirect doctest # optional - sage.libs.pari sage.rings.function_field Valuation at the infinite place """ @@ -1279,10 +1278,10 @@ def is_discrete_valuation(self): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - x^4 - 1) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w0,w1 = v.extensions(L) # optional - sage.libs.pari - sage: w0.is_discrete_valuation() # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x^4 - 1) # optional - sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.function_field + sage: w0,w1 = v.extensions(L) # optional - sage.rings.function_field + sage: w0.is_discrete_valuation() # optional - sage.rings.function_field True """ @@ -1345,7 +1344,9 @@ class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_ sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) sage: w = K.valuation(w) sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v - Valuation on rational function field induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] (in Rational function field in x over Rational Field after x |--> 1/x) + Valuation on rational function field induced by + [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] + (in Rational function field in x over Rational Field after x |--> 1/x) """ def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain): @@ -1418,21 +1419,21 @@ class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: w(x) # optional - sage.libs.pari + sage: w(x) # optional - sage.libs.pari sage.rings.function_field -1 - sage: w(y) # optional - sage.libs.pari + sage: w(y) # optional - sage.libs.pari sage.rings.function_field -3/2 - sage: w.uniformizer() # optional - sage.libs.pari + sage: w.uniformizer() # optional - sage.libs.pari sage.rings.function_field 1/x^2*y TESTS:: sage: from sage.rings.function_field.valuation import FunctionFieldExtensionMappedValuation - sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari + sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari sage.rings.function_field True """ @@ -1444,16 +1445,16 @@ def _repr_(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L); w # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.rings.function_field + sage: w = v.extension(L); w # optional - sage.libs.pari sage.rings.function_field Valuation at the infinite place sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^2 - 1/x^2 - 1) # optional - sage.libs.singular - sage: v = K.valuation(1/x) # optional - sage.libs.singular - sage: w = v.extensions(L); w # optional - sage.libs.singular + sage: L. = K.extension(y^2 - 1/x^2 - 1) # optional - sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.function_field + sage: w = v.extensions(L); w # optional - sage.rings.function_field [[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation, [ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation] @@ -1471,10 +1472,10 @@ def restriction(self, ring): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari - sage: w.restriction(K) is v # optional - sage.libs.pari + sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: w.restriction(K) is v # optional - sage.libs.pari sage.rings.function_field True """ if ring.is_subring(self.domain().base()): diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index 3e30a43248a..729c85e37d6 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -1,4 +1,5 @@ # sage.doctest: optional - sage.libs.pari +# sage.doctest: optional - sage.rings.function_field r""" Valuation rings of function fields From 77ee28215ed5782311378c0f96ad92e3231e61de Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 15 Mar 2023 23:22:57 -0700 Subject: [PATCH 32/54] src/doc/en/reference/function_fields/index.rst: Add new modules --- src/doc/en/reference/function_fields/index.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/en/reference/function_fields/index.rst b/src/doc/en/reference/function_fields/index.rst index 06a92de1707..b9be6e742ea 100644 --- a/src/doc/en/reference/function_fields/index.rst +++ b/src/doc/en/reference/function_fields/index.rst @@ -12,13 +12,25 @@ algebraic closure of `\QQ`. sage/rings/function_field/function_field sage/rings/function_field/element + sage/rings/function_field/element_rational + sage/rings/function_field/element_polymod sage/rings/function_field/order + sage/rings/function_field/order_rational + sage/rings/function_field/order_basis + sage/rings/function_field/order_polymod sage/rings/function_field/ideal + sage/rings/function_field/ideal_rational + sage/rings/function_field/ideal_polymod sage/rings/function_field/place + sage/rings/function_field/place_rational + sage/rings/function_field/place_polymod sage/rings/function_field/divisor sage/rings/function_field/differential sage/rings/function_field/valuation_ring + sage/rings/function_field/valuation sage/rings/function_field/derivations + sage/rings/function_field/derivations_rational + sage/rings/function_field/derivations_polymod sage/rings/function_field/maps sage/rings/function_field/extensions sage/rings/function_field/constructor From 96bd60839ada277469d233cc415b9a255ee2705b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 00:13:40 -0700 Subject: [PATCH 33/54] src/sage/rings/function_field: Fix some imports --- src/sage/rings/function_field/element_polymod.pyx | 2 +- src/sage/rings/function_field/function_field_rational.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index a794d82f6f2..c46923f0aef 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -373,7 +373,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): if deg == 1: return self._parent(self._x[0].nth_root(self._parent.characteristic())) - from .function_field import RationalFunctionField + from .function_field_rational import RationalFunctionField if not isinstance(self.base_ring(), RationalFunctionField): raise NotImplementedError("only implemented for simple extensions of function fields") # compute a representation of the generator y of the field in terms of powers of y^p diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index f36047cda04..ada2d9fb362 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -858,7 +858,7 @@ def higher_derivation(self): sage: [d(x^9,i) for i in range(10)] # optional - sage.modules [x^9, 9*x^8, 36*x^7, 84*x^6, 126*x^5, 126*x^4, 84*x^3, 36*x^2, 9*x, 1] """ - from .derivations import FunctionFieldHigherDerivation_char_zero + from .derivations_polymod import FunctionFieldHigherDerivation_char_zero return FunctionFieldHigherDerivation_char_zero(self) @@ -988,5 +988,5 @@ def higher_derivation(self): sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] """ - from .derivations import RationalFunctionFieldHigherDerivation_global + from .derivations_polymod import RationalFunctionFieldHigherDerivation_global return RationalFunctionFieldHigherDerivation_global(self) From 699d6ffbca97f1eafa4e9e1c2532773b126360f7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 12:04:22 -0700 Subject: [PATCH 34/54] src/doc/en/reference/valuations/index.rst: Update module name in sage.rings.function_field --- src/doc/en/reference/valuations/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/reference/valuations/index.rst b/src/doc/en/reference/valuations/index.rst index 90a8c3c97f7..bd09af43248 100644 --- a/src/doc/en/reference/valuations/index.rst +++ b/src/doc/en/reference/valuations/index.rst @@ -201,7 +201,7 @@ More Details sage/rings/valuation/mapped_valuation sage/rings/valuation/scaled_valuation - sage/rings/function_field/function_field_valuation + sage/rings/function_field/valuation sage/rings/padics/padic_valuation .. include:: ../footer.txt From 83b0be1c81c5e97cba6911a94e784a115440bae5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 00:39:43 -0700 Subject: [PATCH 35/54] src/sage/rings/function_field/function_field.py: try...except for import of FunctionField_polymod --- src/sage/rings/function_field/function_field.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 2af6c5231ab..a4e0dbe1cf1 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -757,7 +757,10 @@ def _convert_map_from_(self, R): sage: K(L(x)) # indirect doctest # optional - sage.rings.function_field x """ - from .function_field_polymod import FunctionField_polymod + try: + from .function_field_polymod import FunctionField_polymod + except ImportError: + FunctionField_polymod = () if isinstance(R, FunctionField_polymod): base_conversion = self.convert_map_from(R.base_field()) if base_conversion is not None: From 0e6a9230e323d1f5cd95e2a4d2b8644c7ae58b19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 13:11:43 -0700 Subject: [PATCH 36/54] sage.rings.function_field: More # optional --- .../rings/function_field/function_field.py | 47 ++++++++++--------- .../rings/function_field/ideal_rational.py | 8 ++-- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index a4e0dbe1cf1..77fef347218 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -866,48 +866,49 @@ def valuation(self, prime): function field:: sage: K. = FunctionField(QQ) - sage: v = K.valuation(1); v + sage: v = K.valuation(1); v # optional - sage.rings.function_field (x - 1)-adic valuation - sage: v(x) + sage: v(x) # optional - sage.rings.function_field 0 - sage: v(x - 1) + sage: v(x - 1) # optional - sage.rings.function_field 1 A place can also be specified with an irreducible polynomial:: - sage: v = K.valuation(x - 1); v + sage: v = K.valuation(x - 1); v # optional - sage.rings.function_field (x - 1)-adic valuation Similarly, for a finite non-rational place:: - sage: v = K.valuation(x^2 + 1); v + sage: v = K.valuation(x^2 + 1); v # optional - sage.rings.function_field (x^2 + 1)-adic valuation - sage: v(x^2 + 1) + sage: v(x^2 + 1) # optional - sage.rings.function_field 1 - sage: v(x) + sage: v(x) # optional - sage.rings.function_field 0 Or for the infinite place:: - sage: v = K.valuation(1/x); v + sage: v = K.valuation(1/x); v # optional - sage.rings.function_field Valuation at the infinite place - sage: v(x) + sage: v(x) # optional - sage.rings.function_field -1 Instead of specifying a generator of a place, we can define a valuation on a rational function field by giving a discrete valuation on the underlying polynomial ring:: - sage: R. = QQ[] - sage: w = valuations.GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) - sage: v = K.valuation(w); v + sage: R. = QQ[] # optional - sage.rings.function_field + sage: u = valuations.GaussValuation(R, valuations.TrivialValuation(QQ)) # optional - sage.rings.function_field + sage: w = u.augmentation(x - 1, 1) # optional - sage.rings.function_field + sage: v = K.valuation(w); v # optional - sage.rings.function_field (x - 1)-adic valuation Note that this allows us to specify valuations which do not correspond to a place of the function field:: - sage: w = valuations.GaussValuation(R, QQ.valuation(2)) - sage: v = K.valuation(w); v + sage: w = valuations.GaussValuation(R, QQ.valuation(2)) # optional - sage.rings.function_field + sage: v = K.valuation(w); v # optional - sage.rings.function_field 2-adic valuation The same is possible for valuations with `v(1/x) > 0` by passing in an @@ -917,18 +918,20 @@ def valuation(self, prime): applying the substitution `x \mapsto 1/x` (here, the inverse map is also `x \mapsto 1/x`):: - sage: w = valuations.GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) - sage: w = K.valuation(w) - sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v - Valuation on rational function field induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] (in Rational function field in x over Rational Field after x |--> 1/x) + sage: w = valuations.GaussValuation(R, QQ.valuation(2)).augmentation(x, 1) # optional - sage.rings.function_field + sage: w = K.valuation(w) # optional - sage.rings.function_field + sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v # optional - sage.rings.function_field + Valuation on rational function field + induced by [ Gauss valuation induced by 2-adic valuation, v(x) = 1 ] + (in Rational function field in x over Rational Field after x |--> 1/x) Note that classical valuations at finite places or the infinite place are always normalized such that the uniformizing element has valuation 1:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: M. = FunctionField(K) # optional - sage.libs.pari - sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari - sage: v(x^3 - t) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari sage.rings.function_field + sage: M. = FunctionField(K) # optional - sage.libs.pari sage.rings.function_field + sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari sage.rings.function_field + sage: v(x^3 - t) # optional - sage.libs.pari sage.rings.function_field 1 However, if such a valuation comes out of a base change of the ground diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index d15861aeff9..4ec75b2eb45 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -307,13 +307,13 @@ def _valuation(self, ideal): sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: p = O.ideal(x) - sage: p.valuation(O.ideal(x + 1)) # indirect doctest + sage: p.valuation(O.ideal(x + 1)) # indirect doctest # optional - sage.libs.pari 0 - sage: p.valuation(O.ideal(x^2)) # indirect doctest + sage: p.valuation(O.ideal(x^2)) # indirect doctest # optional - sage.libs.pari 2 - sage: p.valuation(O.ideal(1/x^3)) # indirect doctest + sage: p.valuation(O.ideal(1/x^3)) # indirect doctest # optional - sage.libs.pari -3 - sage: p.valuation(O.ideal(0)) # indirect doctest + sage: p.valuation(O.ideal(0)) # indirect doctest # optional - sage.libs.pari +Infinity """ return ideal.gen().valuation(self.gen()) From 8b7c7c60d711dfd3a6dff9426ff5dbb8f6f88b19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 17:28:37 -0700 Subject: [PATCH 37/54] src/sage/rings/function_field: Add/update copyright, according to 'git blame -w --date=format:%Y src/sage/rings/function_field/valuation_ring.py | sort -k2' --- src/sage/rings/function_field/constructor.py | 8 +++++--- src/sage/rings/function_field/differential.py | 4 +++- src/sage/rings/function_field/divisor.py | 3 ++- src/sage/rings/function_field/element.pyx | 14 ++++++++++---- src/sage/rings/function_field/extensions.py | 9 +++++++++ .../rings/function_field/function_field.py | 19 +++++++++++++++---- src/sage/rings/function_field/ideal.py | 8 ++++++-- src/sage/rings/function_field/maps.py | 10 ++++++++-- src/sage/rings/function_field/order.py | 8 +++++--- src/sage/rings/function_field/place.py | 4 +++- .../rings/function_field/valuation_ring.py | 2 +- 11 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index 5625934dd84..f0ceab2b412 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -25,9 +25,11 @@ """ #***************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2011 Maarten Derickx -# Copyright (C) 2011 Julian Rueth +# Copyright (C) 2010 William Stein +# 2011 Maarten Derickx +# 2011-2014 Julian Rueth +# 2012 Travis Scrimshaw +# 2017-2019 Kwankyu Lee # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index 4ad17fd18e1..ccc1f03d6cf 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -46,7 +46,9 @@ """ #***************************************************************************** -# Copyright (C) 2016 Kwankyu Lee +# Copyright (C) 2016-2019 Kwankyu Lee +# 2019 Brent Baccala +# 2019 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 054e1044e8a..ad323956719 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -40,7 +40,8 @@ """ #***************************************************************************** -# Copyright (C) 2016 Kwankyu Lee +# Copyright (C) 2016-2022 Kwankyu Lee +# 2019 Brent Baccala # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index e19c07ee36a..277acefc299 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -48,10 +48,16 @@ AUTHORS: """ # **************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2010 Robert Bradshaw -# Copyright (C) 2011-2020 Julian Rueth -# Copyright (C) 2011 Maarten Derickx +# Copyright (C) 2010 William Stein +# 2010 Robert Bradshaw +# 2011-2020 Julian Rueth +# 2011 Maarten Derickx +# 2015 Nils Bruin +# 2016 Frédéric Chapoton +# 2017-2019 Kwankyu Lee +# 2018-2020 Travis Scrimshaw +# 2019 Brent Baccala +# 2021 Saher Amasha # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index 53b10d27f33..f226cddd865 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -52,6 +52,15 @@ """ +# **************************************************************************** +# Copyright (C) 2021-2022 Kwankyu Lee +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from sage.rings.ring_extension import RingExtension_generic from .constructor import FunctionField diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 77fef347218..b45e6a3bf01 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -211,10 +211,21 @@ """ # **************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2010 Robert Bradshaw -# Copyright (C) 2011-2018 Julian Rüth -# Copyright (C) 2011 Maarten Derickx +# Copyright (C) 2010 William Stein +# 2010 Robert Bradshaw +# 2011-2018 Julian Rüth +# 2011 Maarten Derickx +# 2011 Syed Ahmad Lavasani +# 2013-2014 Simon King +# 2017 Dean Bisogno +# 2017 Alyson Deines +# 2017-2019 David Roe +# 2017-2022 Kwankyu Lee +# 2018 Marc Mezzarobba +# 2018 Wilfried Luebbe +# 2019 Brent Baccala +# 2022 Frédéric Chapoton +# 2022 Gonzalo Tornaría # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index ee3aebbc165..d83a11af965 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -79,8 +79,12 @@ """ # **************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2011 Maarten Derickx +# Copyright (C) 2010 William Stein +# 2011 Maarten Derickx +# 2017-2021 Kwankyu Lee +# 2018 Frédéric Chapoton +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 951cc8bd73e..4cfd95414ff 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -35,8 +35,14 @@ """ # **************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2011-2017 Julian Rüth +# Copyright (C) 2010 William Stein +# 2011-2017 Julian Rüth +# 2017 Alyson Deines +# 2017-2019 Kwankyu Lee +# 2018-2019 Travis Scrimshaw +# 2019 Brent Baccala +# 2022 Xavier Caruso +# 2022 Frédéric Chapoton # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index d0ccca9f1d2..b8358e2e002 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -96,9 +96,11 @@ """ #***************************************************************************** -# Copyright (C) 2010 William Stein -# Copyright (C) 2011 Maarten Derickx -# Copyright (C) 2011 Julian Rueth +# Copyright (C) 2010 William Stein +# 2011 Maarten Derickx +# 2011 Julian Rueth +# 2017-2020 Kwankyu Lee +# 2019 Brent Baccala # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index f343243261e..55428c11cab 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -48,7 +48,9 @@ """ #***************************************************************************** -# Copyright (C) 2016 Kwankyu Lee +# Copyright (C) 2016-2022 Kwankyu Lee +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index 729c85e37d6..f408d2b4b38 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -56,7 +56,7 @@ """ # **************************************************************************** -# Copyright (C) 2016 Kwankyu Lee +# Copyright (C) 2016-2019 Kwankyu Lee # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of From 1e5ab99a3163f51360b1075983d37c6e743dc6ce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 17:40:04 -0700 Subject: [PATCH 38/54] src/sage/rings/function_field/derivations*.py: Copy copyright here from maps.py --- src/sage/rings/function_field/derivations.py | 15 +++++++++++++++ .../rings/function_field/derivations_polymod.py | 16 ++++++++++++++++ .../rings/function_field/derivations_rational.py | 16 ++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index 89452dcc628..63f68a8ba11 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -20,6 +20,21 @@ - Kwankyu Lee (2017-04-30): added higher derivations and completions """ +# **************************************************************************** +# Copyright (C) 2010 William Stein +# 2011-2017 Julian Rüth +# 2017 Alyson Deines +# 2017-2019 Kwankyu Lee +# 2018-2019 Travis Scrimshaw +# 2019 Brent Baccala +# 2022 Xavier Caruso +# 2022 Frédéric Chapoton +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.derivation import RingDerivationWithoutTwist diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 5348a8669a7..1d323819b5b 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -1,3 +1,19 @@ +# **************************************************************************** +# Copyright (C) 2010 William Stein +# 2011-2017 Julian Rüth +# 2017 Alyson Deines +# 2017-2019 Kwankyu Lee +# 2018-2019 Travis Scrimshaw +# 2019 Brent Baccala +# 2022 Xavier Caruso +# 2022 Frédéric Chapoton +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from sage.arith.misc import binomial from sage.categories.homset import Hom from sage.categories.map import Map diff --git a/src/sage/rings/function_field/derivations_rational.py b/src/sage/rings/function_field/derivations_rational.py index 73760bebf3c..8b0fbc36032 100644 --- a/src/sage/rings/function_field/derivations_rational.py +++ b/src/sage/rings/function_field/derivations_rational.py @@ -1,3 +1,19 @@ +# **************************************************************************** +# Copyright (C) 2010 William Stein +# 2011-2017 Julian Rüth +# 2017 Alyson Deines +# 2017-2019 Kwankyu Lee +# 2018-2019 Travis Scrimshaw +# 2019 Brent Baccala +# 2022 Xavier Caruso +# 2022 Frédéric Chapoton +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + from .derivations import FunctionFieldDerivation From 95511b10e8fef88e287a625b4bf6bc62901f0449 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 18:49:45 -0700 Subject: [PATCH 39/54] src/doc/en/reference/function_fields/index.rst: Revert add of valuation --- src/doc/en/reference/function_fields/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/reference/function_fields/index.rst b/src/doc/en/reference/function_fields/index.rst index b9be6e742ea..cdd34d5ffff 100644 --- a/src/doc/en/reference/function_fields/index.rst +++ b/src/doc/en/reference/function_fields/index.rst @@ -27,7 +27,6 @@ algebraic closure of `\QQ`. sage/rings/function_field/divisor sage/rings/function_field/differential sage/rings/function_field/valuation_ring - sage/rings/function_field/valuation sage/rings/function_field/derivations sage/rings/function_field/derivations_rational sage/rings/function_field/derivations_polymod From 4b816132f3a04877d937ea7772caaa3bda7d8a7d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 18:50:46 -0700 Subject: [PATCH 40/54] src/sage/categories/function_fields.py: Update # optional --- src/sage/categories/function_fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/categories/function_fields.py b/src/sage/categories/function_fields.py index 65a108e4565..0e0c6b45fce 100644 --- a/src/sage/categories/function_fields.py +++ b/src/sage/categories/function_fields.py @@ -56,10 +56,10 @@ def _call_(self, x): sage: C(K) Rational function field in x over Rational Field sage: Ky. = K[] - sage: L = K.extension(y^2 - x) # optional - sage.libs.singular - sage: C(L) # optional - sage.libs.singular + sage: L = K.extension(y^2 - x) # optional - sage.rings.function_field + sage: C(L) # optional - sage.rings.function_field Function field in y defined by y^2 - x - sage: C(L.equation_order()) # optional - sage.libs.singular + sage: C(L.equation_order()) # optional - sage.rings.function_field Function field in y defined by y^2 - x """ try: From 2bd115a5e252e587bff991dbfc66edebc3606dbc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 19:02:02 -0700 Subject: [PATCH 41/54] src/sage/rings/function_field/function_field_polymod.py: Cosmetic doctest changes --- .../rings/function_field/function_field_polymod.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 6aadac3f1d7..e9f058d38d8 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -1223,8 +1223,8 @@ def simple_model(self, name=None): An example with higher degrees:: sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5-x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3-x) # optional - sage.libs.pari + sage: L. = K.extension(y^5 - x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^3 - x) # optional - sage.libs.pari sage: M.simple_model() # optional - sage.libs.pari (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3, Function Field morphism: @@ -1241,8 +1241,8 @@ def simple_model(self, name=None): This also works for inseparable extensions:: sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2-x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2-y) # optional - sage.libs.pari + sage: L. = K.extension(y^2 - x); R. = L[] # optional - sage.libs.pari + sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari sage: M.simple_model() # optional - sage.libs.pari (Function field in z defined by z^4 + x, Function Field morphism: From: Function field in z defined by z^4 + x @@ -1315,9 +1315,9 @@ def primitive_element(self): sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2-x) # optional - sage.libs.pari + sage: L. = K.extension(Y^2 - x) # optional - sage.libs.pari sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(Z^2-y) # optional - sage.libs.pari + sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari sage: M.primitive_element() # optional - sage.libs.pari z """ From 42fc4afb44d0caa62b5b7e6a4f9bb25369fdd483 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 19:05:57 -0700 Subject: [PATCH 42/54] src/sage/rings/function_field/ideal.py: Cosmetic doctest changes --- src/sage/rings/function_field/ideal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index d83a11af965..534a07ee03e 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -233,7 +233,7 @@ def _div_(self, other): sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3+1) # optional - sage.libs.pari + sage: I = O.ideal(x^3 + 1) # optional - sage.libs.pari sage: I / I # optional - sage.libs.pari Ideal (1) of Maximal order of Rational function field in x over Finite Field of size 7 @@ -257,7 +257,7 @@ def gens_reduced(self): sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x, x^2, x^2+x) # optional - sage.libs.pari + sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.libs.pari sage: I.gens_reduced() # optional - sage.libs.pari (x,) """ From d8f4af574db2fc9ab515b426fbd4586fbe54d099 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 19:15:05 -0700 Subject: [PATCH 43/54] src/sage/rings/function_field/order_basis.py: Cosmetic doctest changes --- src/sage/rings/function_field/order_basis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index 586c2348943..3d2f2a1054e 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -214,7 +214,7 @@ def ideal(self, *gens): sage: S = L.equation_order() # optional - sage.libs.pari sage.rings.function_field sage: S.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2-4); I2 # optional - sage.libs.pari sage.rings.function_field + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari sage.rings.function_field Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.rings.function_field True From 45b274bbccdeb2720452dc6679dcc17b4fa74188 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 19:21:45 -0700 Subject: [PATCH 44/54] src/sage/rings/function_field/place*.py: Cosmetic doctest changes --- src/sage/rings/function_field/place.py | 2 +- src/sage/rings/function_field/place_polymod.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 55428c11cab..faf30816da4 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -304,7 +304,7 @@ def divisor(self, multiplicity=1): sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(x + 1,y) # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari sage.rings.function_field sage: P = I.place() # optional - sage.libs.pari sage.rings.function_field sage: P.divisor() # optional - sage.libs.pari sage.rings.function_field Place (x + 1, y) diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index 362ce0c9f62..5615a17c0f0 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -148,7 +148,7 @@ def _gaps_rational(self): sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari + sage: p = O.ideal(x, y).place() # optional - sage.libs.pari sage: p.gaps() # indirect doctest # optional - sage.libs.pari [1, 2, 4] From 913c7e09fc390cd2880eb3a4205ce25cdd72994d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2023 19:49:31 -0700 Subject: [PATCH 45/54] src/sage/rings/function_field/derivations_polymod.py: Cosmetic doctest changes --- .../function_field/derivations_polymod.py | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 1d323819b5b..828ce1e7af6 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -380,7 +380,7 @@ class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 - sage: h(x^2,2) # optional - sage.libs.pari + sage: h(x^2, 2) # optional - sage.libs.pari 1 """ def __init__(self, field): @@ -406,7 +406,7 @@ def _call_with_args(self, f, args=(), kwds={}): sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h(x^2,2) # indirect doctest # optional - sage.libs.pari + sage: h(x^2, 2) # indirect doctest # optional - sage.libs.pari 1 """ return self._derive(f, *args, **kwds) @@ -422,15 +422,15 @@ def _derive(self, f, i, separating_element=None): sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._derive(x^3,0) # optional - sage.libs.pari + sage: h._derive(x^3, 0) # optional - sage.libs.pari x^3 - sage: h._derive(x^3,1) # optional - sage.libs.pari + sage: h._derive(x^3, 1) # optional - sage.libs.pari x^2 - sage: h._derive(x^3,2) # optional - sage.libs.pari + sage: h._derive(x^3, 2) # optional - sage.libs.pari x - sage: h._derive(x^3,3) # optional - sage.libs.pari + sage: h._derive(x^3, 3) # optional - sage.libs.pari 1 - sage: h._derive(x^3,4) # optional - sage.libs.pari + sage: h._derive(x^3, 4) # optional - sage.libs.pari 0 """ F = self._field @@ -614,7 +614,7 @@ def _call_with_args(self, f, args, kwds): sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h(y^2,2) # indirect doctest # optional - sage.libs.pari + sage: h(y^2, 2) # indirect doctest # optional - sage.libs.pari ((x^7 + 1)/x^2)*y^2 + x^3*y """ return self._derive(f, *args, **kwds) @@ -633,15 +633,15 @@ def _derive(self, f, i, separating_element=None): sage: h = L.higher_derivation() # optional - sage.libs.pari sage: y^3 # optional - sage.libs.pari x^3*y + x - sage: h._derive(y^3,0) # optional - sage.libs.pari + sage: h._derive(y^3, 0) # optional - sage.libs.pari x^3*y + x - sage: h._derive(y^3,1) # optional - sage.libs.pari + sage: h._derive(y^3, 1) # optional - sage.libs.pari x^4*y^2 + 1 - sage: h._derive(y^3,2) # optional - sage.libs.pari + sage: h._derive(y^3, 2) # optional - sage.libs.pari x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3,3) # optional - sage.libs.pari + sage: h._derive(y^3, 3) # optional - sage.libs.pari (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3,4) # optional - sage.libs.pari + sage: h._derive(y^3, 4) # optional - sage.libs.pari (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y """ F = self._field @@ -868,9 +868,9 @@ def _derive(self, f, i, separating_element=None): sage: h = L.higher_derivation() sage: y^3 -x^3*y - x - sage: h._derive(y^3,0) + sage: h._derive(y^3, 0) -x^3*y - x - sage: h._derive(y^3,1) + sage: h._derive(y^3, 1) (-21/4*x^4/(x^7 + 27/4))*y^2 + ((-9/2*x^9 - 45/2*x^2)/(x^7 + 27/4))*y + (-9/2*x^7 - 27/4)/(x^7 + 27/4) """ F = self._field From de9a7ad1116ab5e3c85edc137249340258a3221b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 13:55:34 -0700 Subject: [PATCH 46/54] sage.features: Add feature sage.rings.finite_rings --- src/sage/features/sagemath.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 765142fa2c7..13ed70f7da1 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -200,6 +200,29 @@ def __init__(self): [PythonModule('sage.plot.plot')]) +class sage__rings__finite_rings(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.finite_rings`; + specifically, the element implementations using PARI. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__rings__finite_rings + sage: sage__rings__finite_rings().is_present() # optional - sage.rings.finite_rings + FeatureTestResult('sage.rings.finite_rings', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__rings__finite_rings + sage: isinstance(sage__rings__finite_rings(), sage__rings__finite_rings) + True + """ + JoinFeature.__init__(self, 'sage.rings.finite_rings', + [PythonModule('sage.rings.finite_rings.element_pari_ffelt')]) + + class sage__rings__function_field(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.function_field`. @@ -341,6 +364,7 @@ def all_features(): sage__libs__pari(), sage__modules(), sage__plot(), + sage__rings__finite_rings(), sage__rings__function_field(), sage__rings__number_field(), sage__rings__padics(), From 7496d84ea4804903b97b447623d8fe73b8f9b5e0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 13:59:50 -0700 Subject: [PATCH 47/54] sage.rings.function_field, sage.categories.function_fields: Use # optional - sage.rings.finite_rings instead of sage.libs.pari --- src/sage/rings/function_field/constructor.py | 10 +- src/sage/rings/function_field/derivations.py | 8 +- .../function_field/derivations_polymod.py | 204 ++-- src/sage/rings/function_field/differential.py | 302 +++--- src/sage/rings/function_field/divisor.py | 2 +- src/sage/rings/function_field/element.pyx | 154 +-- .../rings/function_field/element_polymod.pyx | 38 +- .../rings/function_field/element_rational.pyx | 58 +- src/sage/rings/function_field/extensions.py | 78 +- .../rings/function_field/function_field.py | 218 ++--- .../function_field/function_field_polymod.py | 402 ++++---- .../function_field/function_field_rational.py | 130 +-- src/sage/rings/function_field/ideal.py | 446 ++++----- .../rings/function_field/ideal_polymod.py | 912 +++++++++--------- .../rings/function_field/ideal_rational.py | 154 +-- src/sage/rings/function_field/maps.py | 198 ++-- src/sage/rings/function_field/order.py | 38 +- src/sage/rings/function_field/order_basis.py | 156 +-- .../rings/function_field/order_polymod.py | 382 ++++---- .../rings/function_field/order_rational.py | 118 +-- src/sage/rings/function_field/place.py | 188 ++-- .../rings/function_field/place_polymod.py | 162 ++-- .../rings/function_field/place_rational.py | 2 +- src/sage/rings/function_field/valuation.py | 184 ++-- .../rings/function_field/valuation_ring.py | 2 +- 25 files changed, 2273 insertions(+), 2273 deletions(-) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index f0ceab2b412..f34024aa03b 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -56,10 +56,10 @@ class FunctionFieldFactory(UniqueFactory): sage: K. = FunctionField(QQ); K Rational function field in x over Rational Field - sage: L. = FunctionField(GF(7)); L # optional - sage.libs.pari + sage: L. = FunctionField(GF(7)); L # optional - sage.rings.finite_rings Rational function field in y over Finite Field of size 7 - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^7 - z - y); M # optional - sage.libs.pari sage.rings.function_field + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^7 - z - y); M # optional - sage.rings.finite_rings sage.rings.function_field Function field in z defined by z^7 + 6*z + 6*y TESTS:: @@ -68,8 +68,8 @@ class FunctionFieldFactory(UniqueFactory): sage: L. = FunctionField(QQ) sage: K is L True - sage: M. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K is M # optional - sage.libs.pari + sage: M. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K is M # optional - sage.rings.finite_rings False sage: N. = FunctionField(QQ) sage: K is N diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index 63f68a8ba11..e849a4e0016 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -4,10 +4,10 @@ For global function fields, which have positive characteristics, the higher derivation is available:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: h = L.higher_derivation() # optional - sage.libs.pari sage.rings.function_field - sage: h(y^2, 2) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings sage.rings.function_field + sage: h(y^2, 2) # optional - sage.rings.finite_rings sage.rings.function_field ((x^7 + 1)/x^2)*y^2 + x^3*y AUTHORS: diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 828ce1e7af6..4d05cc98982 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -172,24 +172,24 @@ def __init__(self, parent, u=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: d = L.derivation() # optional - sage.rings.finite_rings This also works for iterated non-monic extensions:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - 1/x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2*y - x^3) # optional - sage.libs.pari - sage: M.derivation() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - 1/x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^2*y - x^3) # optional - sage.rings.finite_rings + sage: M.derivation() # optional - sage.rings.finite_rings d/dz We can also create a multiple of the canonical derivation:: - sage: M.derivation([x]) # optional - sage.libs.pari + sage: M.derivation([x]) # optional - sage.rings.finite_rings x*d/dz """ FunctionFieldDerivation.__init__(self, parent) @@ -215,15 +215,15 @@ def _call_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d(x) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: d = L.derivation() # optional - sage.rings.finite_rings + sage: d(x) # indirect doctest # optional - sage.rings.finite_rings 0 - sage: d(y) # optional - sage.libs.pari + sage: d(y) # optional - sage.rings.finite_rings 1 - sage: d(y^2) # optional - sage.libs.pari + sage: d(y^2) # optional - sage.rings.finite_rings 0 """ @@ -238,13 +238,13 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 - x) # optional - sage.rings.finite_rings + sage: d = L.derivation() # optional - sage.rings.finite_rings + sage: d # optional - sage.rings.finite_rings d/dy - sage: d + d # optional - sage.libs.pari + sage: d + d # optional - sage.rings.finite_rings 2*d/dy """ return type(self)(self.parent(), [self._u + other._u]) @@ -255,13 +255,13 @@ def _lmul_(self, factor): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: d = L.derivation() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: d = L.derivation() # optional - sage.rings.finite_rings + sage: d # optional - sage.rings.finite_rings d/dy - sage: y * d # optional - sage.libs.pari + sage: y * d # optional - sage.rings.finite_rings y*d/dy """ return type(self)(self.parent(), [factor * self._u]) @@ -277,8 +277,8 @@ class FunctionFieldHigherDerivation(Map): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: F.higher_derivation() # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: F.higher_derivation() # optional - sage.rings.finite_rings Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 @@ -289,9 +289,9 @@ def __init__(self, field): TESTS:: - sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + sage: F. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: TestSuite(h).run(skip='_test_category') # optional - sage.rings.finite_rings """ Map.__init__(self, Hom(field, field, Sets())) self._field = field @@ -307,9 +307,9 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # indirect doctest # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h # indirect doctest # optional - sage.rings.finite_rings Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 @@ -322,9 +322,9 @@ def __eq__(self, other) -> bool: TESTS:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: loads(dumps(h)) == h # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: loads(dumps(h)) == h # optional - sage.rings.finite_rings True """ if isinstance(other, FunctionFieldHigherDerivation): @@ -340,9 +340,9 @@ def _pth_root_in_prime_field(e): sage: from sage.rings.function_field.derivations_polymod import _pth_root_in_prime_field sage: p = 5 - sage: F. = GF(p) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_prime_field(e)^p == e # optional - sage.libs.pari + sage: F. = GF(p) # optional - sage.rings.finite_rings + sage: e = F.random_element() # optional - sage.rings.finite_rings + sage: _pth_root_in_prime_field(e)^p == e # optional - sage.rings.finite_rings True """ return e @@ -356,9 +356,9 @@ def _pth_root_in_finite_field(e): sage: from sage.rings.function_field.derivations_polymod import _pth_root_in_finite_field sage: p = 3 - sage: F. = GF(p^2) # optional - sage.libs.pari - sage: e = F.random_element() # optional - sage.libs.pari - sage: _pth_root_in_finite_field(e)^p == e # optional - sage.libs.pari + sage: F. = GF(p^2) # optional - sage.rings.finite_rings + sage: e = F.random_element() # optional - sage.rings.finite_rings + sage: _pth_root_in_finite_field(e)^p == e # optional - sage.rings.finite_rings True """ return e.pth_root() @@ -374,13 +374,13 @@ class RationalFunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h # optional - sage.rings.finite_rings Higher derivation map: From: Rational function field in x over Finite Field of size 2 To: Rational function field in x over Finite Field of size 2 - sage: h(x^2, 2) # optional - sage.libs.pari + sage: h(x^2, 2) # optional - sage.rings.finite_rings 1 """ def __init__(self, field): @@ -389,9 +389,9 @@ def __init__(self, field): TESTS:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip='_test_category') # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: TestSuite(h).run(skip='_test_category') # optional - sage.rings.finite_rings """ FunctionFieldHigherDerivation.__init__(self, field) @@ -404,9 +404,9 @@ def _call_with_args(self, f, args=(), kwds={}): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h(x^2, 2) # indirect doctest # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h(x^2, 2) # indirect doctest # optional - sage.rings.finite_rings 1 """ return self._derive(f, *args, **kwds) @@ -420,17 +420,17 @@ def _derive(self, f, i, separating_element=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._derive(x^3, 0) # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h._derive(x^3, 0) # optional - sage.rings.finite_rings x^3 - sage: h._derive(x^3, 1) # optional - sage.libs.pari + sage: h._derive(x^3, 1) # optional - sage.rings.finite_rings x^2 - sage: h._derive(x^3, 2) # optional - sage.libs.pari + sage: h._derive(x^3, 2) # optional - sage.rings.finite_rings x - sage: h._derive(x^3, 3) # optional - sage.libs.pari + sage: h._derive(x^3, 3) # optional - sage.rings.finite_rings 1 - sage: h._derive(x^3, 4) # optional - sage.libs.pari + sage: h._derive(x^3, 4) # optional - sage.rings.finite_rings 0 """ F = self._field @@ -487,11 +487,11 @@ def _prime_power_representation(self, f, separating_element=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h._prime_power_representation(x^2 + x + 1) # optional - sage.rings.finite_rings [x + 1, 1] - sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.libs.pari + sage: x^2 + x + 1 == _[0]^2 + _[1]^2 * x # optional - sage.rings.finite_rings True """ F = self._field @@ -537,9 +537,9 @@ def _pth_root(self, c): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: h = F.higher_derivation() # optional - sage.libs.pari - sage: h._pth_root((x^2+1)^2) # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: h = F.higher_derivation() # optional - sage.rings.finite_rings + sage: h._pth_root((x^2+1)^2) # optional - sage.rings.finite_rings x^2 + 1 """ K = self._field @@ -566,14 +566,14 @@ class FunctionFieldHigherDerivation_global(FunctionFieldHigherDerivation): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: h # optional - sage.rings.finite_rings Higher derivation map: From: Function field in y defined by y^3 + x^3*y + x To: Function field in y defined by y^3 + x^3*y + x - sage: h(y^2, 2) # optional - sage.libs.pari + sage: h(y^2, 2) # optional - sage.rings.finite_rings ((x^7 + 1)/x^2)*y^2 + x^3*y """ @@ -583,10 +583,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: TestSuite(h).run(skip=['_test_category']) # optional - sage.rings.finite_rings """ from sage.matrix.constructor import matrix @@ -611,10 +611,10 @@ def _call_with_args(self, f, args, kwds): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h(y^2, 2) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: h(y^2, 2) # indirect doctest # optional - sage.rings.finite_rings ((x^7 + 1)/x^2)*y^2 + x^3*y """ return self._derive(f, *args, **kwds) @@ -628,20 +628,20 @@ def _derive(self, f, i, separating_element=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: y^3 # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: y^3 # optional - sage.rings.finite_rings x^3*y + x - sage: h._derive(y^3, 0) # optional - sage.libs.pari + sage: h._derive(y^3, 0) # optional - sage.rings.finite_rings x^3*y + x - sage: h._derive(y^3, 1) # optional - sage.libs.pari + sage: h._derive(y^3, 1) # optional - sage.rings.finite_rings x^4*y^2 + 1 - sage: h._derive(y^3, 2) # optional - sage.libs.pari + sage: h._derive(y^3, 2) # optional - sage.rings.finite_rings x^10*y^2 + (x^8 + x)*y - sage: h._derive(y^3, 3) # optional - sage.libs.pari + sage: h._derive(y^3, 3) # optional - sage.rings.finite_rings (x^9 + x^2)*y^2 + x^7*y - sage: h._derive(y^3, 4) # optional - sage.libs.pari + sage: h._derive(y^3, 4) # optional - sage.rings.finite_rings (x^22 + x)*y^2 + ((x^21 + x^14 + x^7 + 1)/x)*y """ F = self._field @@ -727,11 +727,11 @@ def _prime_power_representation(self, f, separating_element=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: b = h._prime_power_representation(y) # optional - sage.libs.pari - sage: y == b[0]^2 + b[1]^2 * x # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: b = h._prime_power_representation(y) # optional - sage.rings.finite_rings + sage: y == b[0]^2 + b[1]^2 * x # optional - sage.rings.finite_rings True """ F = self._field @@ -773,10 +773,10 @@ def _pth_root(self, c): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: h = L.higher_derivation() # optional - sage.libs.pari - sage: h._pth_root((x^2 + y^2)^2) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: h = L.higher_derivation() # optional - sage.rings.finite_rings + sage: h._pth_root((x^2 + y^2)^2) # optional - sage.rings.finite_rings y^2 + x^2 """ from sage.modules.free_module_element import vector diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index ccc1f03d6cf..24ea2371040 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -9,35 +9,35 @@ The module of differentials on a function field forms an one-dimensional vector space over the function field:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: f = x + y # optional - sage.libs.pari sage.rings.function_field - sage: g = 1 / y # optional - sage.libs.pari sage.rings.function_field - sage: df = f.differential() # optional - sage.libs.pari sage.rings.function_field - sage: dg = g.differential() # optional - sage.libs.pari sage.rings.function_field - sage: dfdg = f.derivative() / g.derivative() # optional - sage.libs.pari sage.rings.function_field - sage: df == dfdg * dg # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = x + y # optional - sage.rings.finite_rings sage.rings.function_field + sage: g = 1 / y # optional - sage.rings.finite_rings sage.rings.function_field + sage: df = f.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: dg = g.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: dfdg = f.derivative() / g.derivative() # optional - sage.rings.finite_rings sage.rings.function_field + sage: df == dfdg * dg # optional - sage.rings.finite_rings sage.rings.function_field True - sage: df # optional - sage.libs.pari sage.rings.function_field + sage: df # optional - sage.rings.finite_rings sage.rings.function_field (x*y^2 + 1/x*y + 1) d(x) - sage: df.parent() # optional - sage.libs.pari sage.rings.function_field + sage: df.parent() # optional - sage.rings.finite_rings sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x We can compute a canonical divisor:: - sage: k = df.divisor() # optional - sage.libs.pari sage.rings.function_field - sage: k.degree() # optional - sage.libs.pari sage.rings.function_field + sage: k = df.divisor() # optional - sage.rings.finite_rings sage.rings.function_field + sage: k.degree() # optional - sage.rings.finite_rings sage.rings.function_field 4 - sage: k.degree() == 2 * L.genus() - 2 # optional - sage.libs.pari sage.rings.function_field + sage: k.degree() == 2 * L.genus() - 2 # optional - sage.rings.finite_rings sage.rings.function_field True Exact differentials vanish and logarithmic differentials are stable under the Cartier operation:: - sage: df.cartier() # optional - sage.libs.pari sage.rings.function_field + sage: df.cartier() # optional - sage.rings.finite_rings sage.rings.function_field 0 - sage: w = 1/f * df # optional - sage.libs.pari sage.rings.function_field - sage: w.cartier() == w # optional - sage.libs.pari sage.rings.function_field + sage: w = 1/f * df # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.cartier() == w # optional - sage.rings.finite_rings sage.rings.function_field True AUTHORS: @@ -101,10 +101,10 @@ def __init__(self, parent, f, t=None): TESTS:: - sage: F. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari - sage: w = f.differential() # optional - sage.libs.pari - sage: TestSuite(w).run() # optional - sage.libs.pari + sage: F. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: f = x/(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: w = f.differential() # optional - sage.rings.finite_rings + sage: TestSuite(w).run() # optional - sage.rings.finite_rings """ ModuleElement.__init__(self, parent) @@ -119,9 +119,9 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3+x+x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: y.differential() # optional - sage.rings.finite_rings sage.rings.function_field (x*y^2 + 1/x*y) d(x) sage: F. = FunctionField(QQ) @@ -145,10 +145,10 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari - sage: w = y.differential() # optional - sage.libs.pari - sage: latex(w) # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings + sage: w = y.differential() # optional - sage.rings.finite_rings + sage: latex(w) # optional - sage.rings.finite_rings \left( x y^{2} + \frac{1}{x} y \right)\, dx """ if self._f.is_zero(): # zero differential @@ -167,11 +167,11 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: {x.differential(): 1} # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: {x.differential(): 1} # optional - sage.rings.finite_rings sage.rings.function_field {d(x): 1} - sage: {y.differential(): 1} # optional - sage.libs.pari sage.rings.function_field + sage: {y.differential(): 1} # optional - sage.rings.finite_rings sage.rings.function_field {(x*y^2 + 1/x*y) d(x): 1} """ return hash((self.parent(), self._f)) @@ -189,16 +189,16 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w2 = L(x).differential() # optional - sage.libs.pari sage.rings.function_field - sage: w3 = (x*y).differential() # optional - sage.libs.pari sage.rings.function_field - sage: w1 < w2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w2 = L(x).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w3 = (x*y).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 < w2 # optional - sage.rings.finite_rings sage.rings.function_field False - sage: w2 < w1 # optional - sage.libs.pari sage.rings.function_field + sage: w2 < w1 # optional - sage.rings.finite_rings sage.rings.function_field True - sage: w3 == x * w1 + y * w2 # optional - sage.libs.pari sage.rings.function_field + sage: w3 == x * w1 + y * w2 # optional - sage.rings.finite_rings sage.rings.function_field True sage: F. = FunctionField(QQ) @@ -223,11 +223,11 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w2 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field - sage: w1 + w2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w2 = (1/y).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 + w2 # optional - sage.rings.finite_rings sage.rings.function_field (((x^3 + 1)/x^2)*y^2 + 1/x*y) d(x) sage: F. = FunctionField(QQ) @@ -251,11 +251,11 @@ def _div_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w2 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field - sage: w1 / w2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w2 = (1/y).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 / w2 # optional - sage.rings.finite_rings sage.rings.function_field y^2 sage: F. = FunctionField(QQ) @@ -275,11 +275,11 @@ def _neg_(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w1 = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w2 = (-y).differential() # optional - sage.libs.pari sage.rings.function_field - sage: -w1 == w2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w2 = (-y).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: -w1 == w2 # optional - sage.rings.finite_rings sage.rings.function_field True sage: F. = FunctionField(QQ) @@ -302,11 +302,11 @@ def _rmul_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w1 = (1/y).differential() # optional - sage.libs.pari sage.rings.function_field - sage: w2 = (-1/y^2) * y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w1 == w2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 = (1/y).differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w2 = (-1/y^2) * y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w1 == w2 # optional - sage.rings.finite_rings sage.rings.function_field True sage: F. = FunctionField(QQ) @@ -331,26 +331,26 @@ def _acted_upon_(self, f, self_on_left): EXAMPLES:: - sage: K. = FunctionField(GF(31)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x); _. = L[] # optional - sage.libs.pari sage.rings.function_field - sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari sage.rings.function_field - sage: z.differential() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(31)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x); _. = L[] # optional - sage.rings.finite_rings sage.rings.function_field + sage: M. = L.extension(Z^2 - y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: z.differential() # optional - sage.rings.finite_rings sage.rings.function_field (8/x*z) d(x) - sage: 1/(2*z) * y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: 1/(2*z) * y.differential() # optional - sage.rings.finite_rings sage.rings.function_field (8/x*z) d(x) - sage: z * x.differential() # optional - sage.libs.pari sage.rings.function_field + sage: z * x.differential() # optional - sage.rings.finite_rings sage.rings.function_field (z) d(x) - sage: z * (y^2).differential() # optional - sage.libs.pari sage.rings.function_field + sage: z * (y^2).differential() # optional - sage.rings.finite_rings sage.rings.function_field (z) d(x) - sage: z * (z^4).differential() # optional - sage.libs.pari sage.rings.function_field + sage: z * (z^4).differential() # optional - sage.rings.finite_rings sage.rings.function_field (z) d(x) :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: y * x.differential() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: y * x.differential() # optional - sage.rings.finite_rings sage.rings.function_field (y) d(x) """ F = f.parent() @@ -366,10 +366,10 @@ def divisor(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w = (1/y) * y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = (1/y) * y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.divisor() # optional - sage.rings.finite_rings sage.rings.function_field - Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) - Place (x, y) @@ -397,10 +397,10 @@ def valuation(self, place): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w = (1/y) * y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: [w.valuation(p) for p in L.places()] # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = (1/y) * y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: [w.valuation(p) for p in L.places()] # optional - sage.rings.finite_rings sage.rings.function_field [-1, -1, -1, 0, 1, 0] """ F = self.parent().function_field() @@ -424,27 +424,27 @@ def residue(self, place): We verify the residue theorem in a rational function field:: - sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: f = 0 # optional - sage.libs.pari - sage: while f == 0: # optional - sage.libs.pari + sage: F. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: f = 0 # optional - sage.rings.finite_rings + sage: while f == 0: # optional - sage.rings.finite_rings ....: f = F.random_element() - sage: w = 1/f * f.differential() # optional - sage.libs.pari - sage: d = f.divisor() # optional - sage.libs.pari - sage: s = d.support() # optional - sage.libs.pari - sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari + sage: w = 1/f * f.differential() # optional - sage.rings.finite_rings + sage: d = f.divisor() # optional - sage.rings.finite_rings + sage: s = d.support() # optional - sage.rings.finite_rings + sage: sum([w.residue(p).trace() for p in s]) # optional - sage.rings.finite_rings 0 and in an extension field:: - sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: f = 0 # optional - sage.libs.pari sage.rings.function_field - sage: while f == 0: # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = 0 # optional - sage.rings.finite_rings sage.rings.function_field + sage: while f == 0: # optional - sage.rings.finite_rings sage.rings.function_field ....: f = L.random_element() - sage: w = 1/f * f.differential() # optional - sage.libs.pari sage.rings.function_field - sage: d = f.divisor() # optional - sage.libs.pari sage.rings.function_field - sage: s = d.support() # optional - sage.libs.pari sage.rings.function_field - sage: sum([w.residue(p).trace() for p in s]) # optional - sage.libs.pari sage.rings.function_field + sage: w = 1/f * f.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: d = f.divisor() # optional - sage.rings.finite_rings sage.rings.function_field + sage: s = d.support() # optional - sage.rings.finite_rings sage.rings.function_field + sage: sum([w.residue(p).trace() for p in s]) # optional - sage.rings.finite_rings sage.rings.function_field 0 and also in a function field of characteristic zero:: @@ -484,12 +484,12 @@ def monomial_coefficients(self, copy=True): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: d = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: d # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: d = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: d # optional - sage.rings.finite_rings sage.rings.function_field ((4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)) d(x) - sage: d.monomial_coefficients() # optional - sage.libs.pari sage.rings.function_field + sage: d.monomial_coefficients() # optional - sage.rings.finite_rings sage.rings.function_field {0: (4*x/(x^7 + 3))*y^2 + ((4*x^7 + 1)/(x^8 + 3*x))*y + x^4/(x^7 + 3)} """ return {0: self._f} @@ -501,16 +501,16 @@ class FunctionFieldDifferential_global(FunctionFieldDifferential): EXAMPLES:: - sage: F. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari - sage: f.differential() # optional - sage.libs.pari + sage: F. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: f = x/(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: f.differential() # optional - sage.rings.finite_rings ((6*x^2 + 1)/(x^4 + 2*x^3 + 3*x^2 + 2*x + 1)) d(x) :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: y.differential() # optional - sage.rings.finite_rings sage.rings.function_field (x*y^2 + 1/x*y) d(x) """ def cartier(self): @@ -530,19 +530,19 @@ def cartier(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: f = x/y # optional - sage.libs.pari sage.rings.function_field - sage: w = 1/f*f.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w.cartier() == w # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = x/y # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = 1/f*f.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.cartier() == w # optional - sage.rings.finite_rings sage.rings.function_field True :: - sage: F. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: f = x/(x^2 + x + 1) # optional - sage.libs.pari - sage: w = 1/f*f.differential() # optional - sage.libs.pari - sage: w.cartier() == w # optional - sage.libs.pari + sage: F. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: f = x/(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: w = 1/f*f.differential() # optional - sage.rings.finite_rings + sage: w.cartier() == w # optional - sage.rings.finite_rings True """ W = self.parent() @@ -562,9 +562,9 @@ class DifferentialsSpace(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x The space of differentials is a one-dimensional module over the function @@ -574,14 +574,14 @@ class DifferentialsSpace(UniqueRepresentation, Parent): element is automatically found and used to generate the base differential relative to which other differentials are denoted:: - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: L(x).differential() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^5 - 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L(x).differential() # optional - sage.rings.finite_rings sage.rings.function_field 0 - sage: y.differential() # optional - sage.libs.pari sage.rings.function_field + sage: y.differential() # optional - sage.rings.finite_rings sage.rings.function_field d(y) - sage: (y^2).differential() # optional - sage.libs.pari sage.rings.function_field + sage: (y^2).differential() # optional - sage.rings.finite_rings sage.rings.function_field (2*y) d(y) """ Element = FunctionFieldDifferential @@ -592,10 +592,10 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(4)); _.=K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: W = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(W).run() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _.=K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: W = L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(W).run() # optional - sage.rings.finite_rings sage.rings.function_field """ Parent.__init__(self, base=field, category=Modules(field).FiniteDimensional().WithBasis().or_subcategory(category)) @@ -618,10 +618,10 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: w = y.differential() # optional - sage.libs.pari sage.rings.function_field - sage: w.parent() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = y.differential() # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.parent() # optional - sage.rings.finite_rings sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x """ return "Space of differentials of {}".format(self.base()) @@ -636,14 +636,14 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field - sage: S(y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field + sage: S(y) # optional - sage.rings.finite_rings sage.rings.function_field (x*y^2 + 1/x*y) d(x) - sage: S(y) in S # optional - sage.libs.pari sage.rings.function_field + sage: S(y) in S # optional - sage.rings.finite_rings sage.rings.function_field True - sage: S(1) # optional - sage.libs.pari sage.rings.function_field + sage: S(1) # optional - sage.rings.finite_rings sage.rings.function_field 0 """ if f in self.base(): @@ -678,10 +678,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field - sage: S.function_field() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field + sage: S.function_field() # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^3 + x^3*y + x """ return self.base() @@ -692,10 +692,10 @@ def _an_element_(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field - sage: S.an_element() # random # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field + sage: S.an_element() # random # optional - sage.rings.finite_rings sage.rings.function_field (x*y^2 + 1/x*y) d(x) """ F = self.base() @@ -707,10 +707,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: S = L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field - sage: S.basis() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: S = L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field + sage: S.basis() # optional - sage.rings.finite_rings sage.rings.function_field Family (d(x),) """ return Family([self.element_class(self, self.base().one())]) @@ -726,9 +726,9 @@ class DifferentialsSpace_global(DifferentialsSpace): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: L.space_of_differentials() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.rings.finite_rings sage.rings.function_field Space of differentials of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldDifferential_global diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index ad323956719..4646491c7e0 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) +# sage.doctest: optional - sage.rings.finite_rings (because all doctests use finite fields) # sage.doctest: optional - sage.rings.function_field (because almost all doctests use function field extensions) """ Divisors of function fields diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 277acefc299..989b0e964e8 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -20,16 +20,16 @@ Arithmetic with rational functions:: Derivatives of elements in separable extensions:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (y^3 + x).derivative() # optional - sage.rings.finite_rings sage.rings.function_field ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 The divisor of an element of a global function field:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: y.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: y.divisor() # optional - sage.rings.finite_rings sage.rings.function_field - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -390,26 +390,26 @@ cdef class FunctionFieldElement(FieldElement): sage: f.differential() # optional - sage.modules (-1/t^2) d(t) - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (y^3 + x).differential() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x +1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (y^3 + x).differential() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field (((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3) d(x) TESTS: Verify that :trac:`27712` is resolved:: - sage: K. = FunctionField(GF(31)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field - sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(31)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: R. = L[] # optional - sage.rings.finite_rings sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.rings.finite_rings sage.rings.function_field - sage: x.differential() # optional - sage.libs.pari sage.modules + sage: x.differential() # optional - sage.rings.finite_rings sage.modules d(x) - sage: y.differential() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: y.differential() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field (16/x*y) d(x) - sage: z.differential() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: z.differential() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field (8/x*z) d(x) """ F = self.parent() @@ -430,9 +430,9 @@ cdef class FunctionFieldElement(FieldElement): sage: f.derivative() # optional - sage.modules (-t^2 - 2*t - 1/3)/(t^4 - 2/3*t^2 + 1/9) - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (y^3 + x).derivative() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (y^3 + x).derivative() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field ((x^2 + 1)/x^2)*y + (x^4 + x^3 + 1)/x^3 """ D = self.parent().derivation() @@ -452,16 +452,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = t^2 # optional - sage.libs.pari - sage: f.higher_derivative(2) # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = t^2 # optional - sage.rings.finite_rings + sage: f.higher_derivative(2) # optional - sage.rings.finite_rings sage.modules 1 :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (y^3 + x).higher_derivative(2) # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (y^3 + x).higher_derivative(2) # optional - sage.rings.finite_rings sage.modules sage.rings.function_field 1/x^3*y + (x^6 + x^4 + x^3 + x^2 + x + 1)/x^5 """ D = self.parent().higher_derivation() @@ -474,18 +474,18 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/(x^3 + x^2 + x) # optional - sage.rings.finite_rings + sage: f.divisor() # optional - sage.rings.finite_rings sage.modules 3*Place (1/x) - Place (x) - Place (x^2 + x + 1) :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: y.divisor() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: y.divisor() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field - Place (1/x, 1/x*y) - Place (x, x*y) + 2*Place (x + 1, x*y) @@ -504,16 +504,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_zeros() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/(x^3 + x^2 + x) # optional - sage.rings.finite_rings + sage: f.divisor_of_zeros() # optional - sage.rings.finite_rings sage.modules 3*Place (1/x) :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (x/y).divisor_of_zeros() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (x/y).divisor_of_zeros() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field 3*Place (x, x*y) """ if self.is_zero(): @@ -530,17 +530,17 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.divisor_of_poles() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/(x^3 + x^2 + x) # optional - sage.rings.finite_rings + sage: f.divisor_of_poles() # optional - sage.rings.finite_rings sage.modules Place (x) + Place (x^2 + x + 1) :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (x/y).divisor_of_poles() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (x/y).divisor_of_poles() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field Place (1/x, 1/x*y) + 2*Place (x + 1, x*y) """ if self.is_zero(): @@ -557,16 +557,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.zeros() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/(x^3 + x^2 + x) # optional - sage.rings.finite_rings + sage: f.zeros() # optional - sage.rings.finite_rings sage.modules [Place (1/x)] :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: (x/y).zeros() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: (x/y).zeros() # optional - sage.rings.finite_rings sage.modules [Place (x, x*y)] """ return self.divisor_of_zeros().support() @@ -577,16 +577,16 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: f = 1/(x^3 + x^2 + x) # optional - sage.libs.pari - sage: f.poles() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/(x^3 + x^2 + x) # optional - sage.rings.finite_rings + sage: f.poles() # optional - sage.rings.finite_rings sage.modules [Place (x), Place (x^2 + x + 1)] :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: (x/y).poles() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: (x/y).poles() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [Place (1/x, 1/x*y), Place (x + 1, x*y)] """ return self.divisor_of_poles().support() @@ -601,10 +601,10 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_infinite()[0] # optional - sage.libs.pari sage.modules sage.rings.function_field - sage: y.valuation(p) # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_infinite()[0] # optional - sage.rings.finite_rings sage.modules sage.rings.function_field + sage: y.valuation(p) # optional - sage.rings.finite_rings sage.modules sage.rings.function_field -1 :: @@ -636,23 +636,23 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: p = K.place_infinite() # optional - sage.libs.pari - sage: f = 1/t^2 + 3 # optional - sage.libs.pari - sage: f.evaluate(p) # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: p = K.place_infinite() # optional - sage.rings.finite_rings + sage: f = 1/t^2 + 3 # optional - sage.rings.finite_rings + sage: f.evaluate(p) # optional - sage.rings.finite_rings 3 :: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p, = L.places_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: p, = L.places_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: (y + x).evaluate(p) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p, = L.places_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: p, = L.places_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: (y + x).evaluate(p) # optional - sage.rings.finite_rings sage.rings.function_field Traceback (most recent call last): ... ValueError: has a pole at the place - sage: (y/x + 1).evaluate(p) # optional - sage.libs.pari sage.rings.function_field + sage: (y/x + 1).evaluate(p) # optional - sage.rings.finite_rings sage.rings.function_field 1 """ R, fr_R, to_R = place._residue_field() @@ -685,9 +685,9 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: f = (x+1)/(x-1) # optional - sage.libs.pari - sage: f.is_nth_power(2) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: f = (x+1)/(x-1) # optional - sage.rings.finite_rings + sage: f.is_nth_power(2) # optional - sage.rings.finite_rings False """ raise NotImplementedError("is_nth_power() not implemented for generic elements") @@ -711,10 +711,10 @@ cdef class FunctionFieldElement(FieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field - sage: L(y^27).nth_root(27) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L(y^27).nth_root(27) # optional - sage.rings.finite_rings sage.rings.function_field y """ raise NotImplementedError("nth_root() not implemented for generic elements") diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index c46923f0aef..f456af74268 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -265,22 +265,22 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L(y^3).nth_root(3) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: L(y^3).nth_root(3) # optional - sage.rings.finite_rings y - sage: L(y^9).nth_root(-9) # optional - sage.libs.pari + sage: L(y^9).nth_root(-9) # optional - sage.rings.finite_rings 1/x*y This also works for inseparable extensions:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - x^2) # optional - sage.libs.pari - sage: L(x).nth_root(3)^3 # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 - x^2) # optional - sage.rings.finite_rings + sage: L(x).nth_root(3)^3 # optional - sage.rings.finite_rings x - sage: L(x^9).nth_root(-27)^-27 # optional - sage.libs.pari + sage: L(x^9).nth_root(-27)^-27 # optional - sage.rings.finite_rings x^9 """ @@ -326,12 +326,12 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: y.is_nth_power(2) # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: y.is_nth_power(2) # optional - sage.rings.finite_rings False - sage: L(x).is_nth_power(2) # optional - sage.libs.pari + sage: L(x).is_nth_power(2) # optional - sage.rings.finite_rings True """ @@ -363,10 +363,10 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: (y^3).nth_root(3) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: (y^3).nth_root(3) # indirect doctest # optional - sage.rings.finite_rings y """ cdef Py_ssize_t deg = self._parent.degree() diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index f2815c467a5..5d5f8857004 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -48,7 +48,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: sage: K. = FunctionField(QQ) - sage: ((a+1)/(a-1)).__pari__() # optional - sage.libs.pari + sage: ((a+1)/(a-1)).__pari__() # optional - sage.rings.finite_rings (a + 1)/(a - 1) """ @@ -60,16 +60,16 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: t.element() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: t.element() # optional - sage.rings.finite_rings t - sage: type(t.element()) # optional - sage.libs.pari + sage: type(t.element()) # optional - sage.rings.finite_rings <... 'sage.rings.fraction_field_FpT.FpTElement'> - sage: K. = FunctionField(GF(131101)) # optional - sage.libs.pari - sage: t.element() # optional - sage.libs.pari + sage: K. = FunctionField(GF(131101)) # optional - sage.rings.finite_rings + sage: t.element() # optional - sage.rings.finite_rings t - sage: type(t.element()) # optional - sage.libs.pari + sage: type(t.element()) # optional - sage.rings.finite_rings <... 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'> """ return self._x @@ -286,9 +286,9 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: f.valuation(t^2 - 1/3) -3 - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: p = K.places_finite()[0] # optional - sage.libs.pari - sage: (1/x^2).valuation(p) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: p = K.places_finite()[0] # optional - sage.rings.finite_rings + sage: (1/x^2).valuation(p) # optional - sage.rings.finite_rings -2 """ from .place import FunctionFieldPlace @@ -316,10 +316,10 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square() True - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: (-t^2).is_square() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: (-t^2).is_square() # optional - sage.rings.finite_rings True - sage: (-t^2).sqrt() # optional - sage.libs.pari + sage: (-t^2).sqrt() # optional - sage.rings.finite_rings 2*t """ return self._x.is_square() @@ -374,15 +374,15 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: f = (x+1)/(x-1) # optional - sage.libs.pari - sage: f.is_nth_power(1) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: f = (x+1)/(x-1) # optional - sage.rings.finite_rings + sage: f.is_nth_power(1) # optional - sage.rings.finite_rings True - sage: f.is_nth_power(3) # optional - sage.libs.pari + sage: f.is_nth_power(3) # optional - sage.rings.finite_rings False - sage: (f^3).is_nth_power(3) # optional - sage.libs.pari + sage: (f^3).is_nth_power(3) # optional - sage.rings.finite_rings True - sage: (f^9).is_nth_power(-9) # optional - sage.libs.pari + sage: (f^9).is_nth_power(-9) # optional - sage.rings.finite_rings True """ if n == 1: @@ -425,17 +425,17 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): EXAMPLES:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: f = (x+1)/(x+2) # optional - sage.libs.pari - sage: f.nth_root(1) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: f = (x+1)/(x+2) # optional - sage.rings.finite_rings + sage: f.nth_root(1) # optional - sage.rings.finite_rings (x + 1)/(x + 2) - sage: f.nth_root(3) # optional - sage.libs.pari + sage: f.nth_root(3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: element is not an n-th power - sage: (f^3).nth_root(3) # optional - sage.libs.pari + sage: (f^3).nth_root(3) # optional - sage.rings.finite_rings (x + 1)/(x + 2) - sage: (f^9).nth_root(-9) # optional - sage.libs.pari + sage: (f^9).nth_root(-9) # optional - sage.rings.finite_rings (x + 2)/(x + 1) """ if n == 0: @@ -464,13 +464,13 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): sage: K. = FunctionField(QQ) sage: f = (t+1) / (t^2 - 1/3) - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # optional - sage.rings.finite_rings (t + 1) * (t^2 - 1/3)^-1 - sage: (7*f).factor() # optional - sage.libs.pari + sage: (7*f).factor() # optional - sage.rings.finite_rings (7) * (t + 1) * (t^2 - 1/3)^-1 - sage: ((7*f).factor()).unit() # optional - sage.libs.pari + sage: ((7*f).factor()).unit() # optional - sage.rings.finite_rings 7 - sage: (f^3).factor() # optional - sage.libs.pari + sage: (f^3).factor() # optional - sage.rings.finite_rings (t + 1)^3 * (t^2 - 1/3)^-3 """ P = self.parent() diff --git a/src/sage/rings/function_field/extensions.py b/src/sage/rings/function_field/extensions.py index f226cddd865..10a81cc3c1e 100644 --- a/src/sage/rings/function_field/extensions.py +++ b/src/sage/rings/function_field/extensions.py @@ -27,20 +27,20 @@ Constant field extension of a function field over a finite field:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: E # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^3 + x^6 + x^4 + x^2 over its base - sage: p = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field - sage: E.conorm_place(p) # random # optional - sage.libs.pari sage.rings.function_field + sage: p = F.get_place(3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E.conorm_place(p) # random # optional - sage.rings.finite_rings sage.rings.function_field Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) + Place (x + z3^2 + z3, y + z3^2) - sage: q = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field - sage: E.conorm_place(q) # random # optional - sage.libs.pari sage.rings.function_field + sage: q = F.get_place(2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E.conorm_place(q) # random # optional - sage.rings.finite_rings sage.rings.function_field Place (x + 1, y^2 + y + 1) - sage: E.conorm_divisor(p + q) # random # optional - sage.libs.pari sage.rings.function_field + sage: E.conorm_divisor(p + q) # random # optional - sage.rings.finite_rings sage.rings.function_field Place (x + 1, y^2 + y + 1) + Place (x + z3, y + z3^2 + z3) + Place (x + z3^2, y + z3) @@ -90,10 +90,10 @@ def __init__(self, F, k_ext): TESTS:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(E).run(skip=['_test_elements', '_test_pickling']) # optional - sage.rings.finite_rings sage.rings.function_field """ k = F.constant_base_field() F_base = F.base_field() @@ -129,10 +129,10 @@ def top(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: E.top() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E.top() # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return self._F_ext @@ -145,10 +145,10 @@ def defining_morphism(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: E.defining_morphism() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E.defining_morphism() # optional - sage.rings.finite_rings sage.rings.function_field Function Field morphism: From: Function field in y defined by y^3 + x^6 + x^4 + x^2 To: Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -170,16 +170,16 @@ def conorm_place(self, p): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: p = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field - sage: d = E.conorm_place(p) # optional - sage.libs.pari sage.rings.function_field - sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = F.get_place(3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: d = E.conorm_place(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: [pl.degree() for pl in d.support()] # optional - sage.rings.finite_rings sage.rings.function_field [1, 1, 1] - sage: p = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field - sage: d = E.conorm_place(p) # optional - sage.libs.pari sage.rings.function_field - sage: [pl.degree() for pl in d.support()] # optional - sage.libs.pari sage.rings.function_field + sage: p = F.get_place(2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: d = E.conorm_place(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: [pl.degree() for pl in d.support()] # optional - sage.rings.finite_rings sage.rings.function_field [2] """ embedF = self.defining_morphism() @@ -206,15 +206,15 @@ def conorm_divisor(self, d): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.libs.pari sage.rings.function_field - sage: p1 = F.get_place(3) # optional - sage.libs.pari sage.rings.function_field - sage: p2 = F.get_place(2) # optional - sage.libs.pari sage.rings.function_field - sage: c = E.conorm_divisor(2*p1 + 3*p2) # optional - sage.libs.pari sage.rings.function_field - sage: c1 = E.conorm_place(p1) # optional - sage.libs.pari sage.rings.function_field - sage: c2 = E.conorm_place(p2) # optional - sage.libs.pari sage.rings.function_field - sage: c == 2*c1 + 3*c2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1 = F.get_place(3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p2 = F.get_place(2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: c = E.conorm_divisor(2*p1 + 3*p2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: c1 = E.conorm_place(p1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: c2 = E.conorm_place(p2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: c == 2*c1 + 3*c2 # optional - sage.rings.finite_rings sage.rings.function_field True """ div_top = self.divisor_group() diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index b45e6a3bf01..76bf62d3a10 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -9,57 +9,57 @@ We create a rational function field:: - sage: K. = FunctionField(GF(5^2,'a')); K # optional - sage.libs.pari + sage: K. = FunctionField(GF(5^2,'a')); K # optional - sage.rings.finite_rings Rational function field in x over Finite Field in a of size 5^2 - sage: K.genus() # optional - sage.libs.pari + sage: K.genus() # optional - sage.rings.finite_rings 0 - sage: f = (x^2 + x + 1) / (x^3 + 1) # optional - sage.libs.pari - sage: f # optional - sage.libs.pari + sage: f = (x^2 + x + 1) / (x^3 + 1) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings (x^2 + x + 1)/(x^3 + 1) - sage: f^3 # optional - sage.libs.pari + sage: f^3 # optional - sage.rings.finite_rings (x^6 + 3*x^5 + x^4 + 2*x^3 + x^2 + 3*x + 1)/(x^9 + 3*x^6 + 3*x^3 + 1) Then we create an extension of the rational function field, and do some simple arithmetic in it:: - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.libs.pari sage.rings.function_field + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: y^2 # optional - sage.libs.pari sage.rings.function_field + sage: y^2 # optional - sage.rings.finite_rings sage.rings.function_field y^2 - sage: y^3 # optional - sage.libs.pari sage.rings.function_field + sage: y^3 # optional - sage.rings.finite_rings sage.rings.function_field 2*x*y + (x^4 + 1)/x - sage: a = 1/y; a # optional - sage.libs.pari sage.rings.function_field + sage: a = 1/y; a # optional - sage.rings.finite_rings sage.rings.function_field (x/(x^4 + 1))*y^2 + 3*x^2/(x^4 + 1) - sage: a * y # optional - sage.libs.pari sage.rings.function_field + sage: a * y # optional - sage.rings.finite_rings sage.rings.function_field 1 We next make an extension of the above function field, illustrating that arithmetic with a tower of three fields is fully supported:: - sage: S. = L[] # optional - sage.libs.pari - sage: M. = L.extension(t^2 - x*y) # optional - sage.libs.pari sage.rings.function_field - sage: M # optional - sage.libs.pari sage.rings.function_field + sage: S. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(t^2 - x*y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: M # optional - sage.rings.finite_rings sage.rings.function_field Function field in t defined by t^2 + 4*x*y - sage: t^2 # optional - sage.libs.pari sage.rings.function_field + sage: t^2 # optional - sage.rings.finite_rings sage.rings.function_field x*y - sage: 1/t # optional - sage.libs.pari sage.rings.function_field + sage: 1/t # optional - sage.rings.finite_rings sage.rings.function_field ((1/(x^4 + 1))*y^2 + 3*x/(x^4 + 1))*t - sage: M.base_field() # optional - sage.libs.pari sage.rings.function_field + sage: M.base_field() # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x - sage: M.base_field().base_field() # optional - sage.libs.pari sage.rings.function_field + sage: M.base_field().base_field() # optional - sage.rings.finite_rings sage.rings.function_field Rational function field in x over Finite Field in a of size 5^2 It is also possible to construct function fields over an imperfect base field:: - sage: N. = FunctionField(K) # optional - sage.libs.pari + sage: N. = FunctionField(K) # optional - sage.rings.finite_rings and inseparable extension function fields:: - sage: J. = FunctionField(GF(5)); J # optional - sage.libs.pari + sage: J. = FunctionField(GF(5)); J # optional - sage.rings.finite_rings Rational function field in x over Finite Field of size 5 - sage: T. = J[] # optional - sage.libs.pari - sage: O. = J.extension(v^5 - x); O # optional - sage.libs.pari sage.rings.function_field + sage: T. = J[] # optional - sage.rings.finite_rings + sage: O. = J.extension(v^5 - x); O # optional - sage.rings.finite_rings sage.rings.function_field Function field in v defined by v^5 + 4*x Function fields over the rational field are supported:: @@ -117,14 +117,14 @@ TESTS:: - sage: TestSuite(J).run() # optional - sage.libs.pari + sage: TestSuite(J).run() # optional - sage.rings.finite_rings sage: TestSuite(K).run(max_runs=256) # long time (10s) # optional - sage.rings.number_field sage: TestSuite(L).run(max_runs=8) # long time (25s) # optional - sage.rings.function_field sage.rings.number_field sage: TestSuite(M).run(max_runs=8) # long time (35s) sage: TestSuite(N).run(max_runs=8, skip = '_test_derivation') # long time (15s) sage: TestSuite(O).run() # optional - sage.rings.function_field sage.rings.number_field sage: TestSuite(R).run() - sage: TestSuite(S).run() # long time (4s) # optional - sage.libs.pari sage.rings.function_field + sage: TestSuite(S).run() # long time (4s) # optional - sage.rings.finite_rings sage.rings.function_field Global function fields ---------------------- @@ -139,31 +139,31 @@ of its maximal order and maximal infinite order, and then do arithmetic with ideals of those maximal orders:: - sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.basis() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.basis() # optional - sage.rings.finite_rings sage.rings.function_field (1, y, 1/x*y^2 + 1/x*y, 1/x^3*y^3 + 2/x^3*y^2 + 1/x^3*y) - sage: I = O.ideal(x,y); I # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal(x,y); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (x, y) of Maximal order of Function field in y defined by y^4 + y + 2*x^5 - sage: J = I^-1 # optional - sage.libs.pari sage.rings.function_field - sage: J.basis_matrix() # optional - sage.libs.pari sage.rings.function_field + sage: J = I^-1 # optional - sage.rings.finite_rings sage.rings.function_field + sage: J.basis_matrix() # optional - sage.rings.finite_rings sage.rings.function_field [ 1 0 0 0] [1/x 1/x 0 0] [ 0 0 1 0] [ 0 0 0 1] - sage: L.maximal_order_infinite().basis() # optional - sage.libs.pari sage.rings.function_field + sage: L.maximal_order_infinite().basis() # optional - sage.rings.finite_rings sage.rings.function_field (1, 1/x^2*y, 1/x^3*y^2, 1/x^4*y^3) As an example of the most sophisticated computations that Sage can do with a global function field, we compute all the Weierstrass places of the Klein quartic over `\GF{2}` and gap numbers for ordinary places:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: L.genus() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.genus() # optional - sage.rings.finite_rings sage.rings.function_field 3 - sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: L.weierstrass_places() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -174,17 +174,17 @@ Place (x^3 + x^2 + 1, y + x), Place (x^3 + x^2 + 1, y + x^2 + 1), Place (x^3 + x^2 + 1, y + x^2 + x + 1)] - sage: L.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: L.gaps() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [1, 2, 3] The gap numbers for Weierstrass places are of course not ordinary:: - sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.libs.pari sage.modules sage.rings.function_field - sage: p1.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: p1,p2,p3 = L.weierstrass_places()[:3] # optional - sage.rings.finite_rings sage.modules sage.rings.function_field + sage: p1.gaps() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [1, 2, 4] - sage: p2.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: p2.gaps() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [1, 2, 4] - sage: p3.gaps() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: p3.gaps() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [1, 2, 4] AUTHORS: @@ -303,7 +303,7 @@ def is_perfect(self): sage: FunctionField(QQ, 'x').is_perfect() True - sage: FunctionField(GF(2), 'x').is_perfect() # optional - sage.libs.pari + sage: FunctionField(GF(2), 'x').is_perfect() # optional - sage.rings.finite_rings False """ return self.characteristic() == 0 @@ -369,12 +369,12 @@ def characteristic(self): sage: K. = FunctionField(QQbar) # optional - sage.rings.number_field sage: K.characteristic() # optional - sage.rings.number_field 0 - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.characteristic() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.characteristic() # optional - sage.rings.finite_rings 7 - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari sage.rings.function_field - sage: L.characteristic() # optional - sage.libs.pari sage.rings.function_field + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.characteristic() # optional - sage.rings.finite_rings sage.rings.function_field 7 """ return self.constant_base_field().characteristic() @@ -388,8 +388,8 @@ def is_finite(self): sage: R. = FunctionField(QQ) sage: R.is_finite() False - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: R.is_finite() # optional - sage.libs.pari + sage: R. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: R.is_finite() # optional - sage.rings.finite_rings False """ return False @@ -407,8 +407,8 @@ def is_global(self): sage: R. = FunctionField(QQbar) # optional - sage.rings.number_field sage: R.is_global() # optional - sage.rings.number_field False - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: R.is_global() # optional - sage.libs.pari + sage: R. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: R.is_global() # optional - sage.rings.finite_rings True """ return self.constant_base_field().is_finite() @@ -646,7 +646,7 @@ def _coerce_map_from_(self, source): Conversion map: From: Order in Function field in y defined by y^3 + x^3 + 4*x + 1 To: Function field in y defined by y^3 + x^3 + 4*x + 1 - sage: L._coerce_map_from_(GF(7)) # optional - sage.libs.pari sage.rings.function_field + sage: L._coerce_map_from_(GF(7)) # optional - sage.rings.finite_rings sage.rings.function_field sage: K. = FunctionField(QQ) sage: L. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field @@ -655,7 +655,7 @@ def _coerce_map_from_(self, source): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(y^3 + 1) # optional - sage.libs.pari sage.rings.function_field + sage: L. = K.extension(y^3 + 1) # optional - sage.rings.finite_rings sage.rings.function_field sage: K. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field sage: R. = K[] # optional - sage.rings.number_field sage: M. = K.extension(y^3 + 1) # optional - sage.rings.function_field @@ -664,9 +664,9 @@ def _coerce_map_from_(self, source): sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(I^2 + 1) # optional - sage.libs.pari sage.rings.function_field + sage: L. = K.extension(I^2 + 1) # optional - sage.rings.finite_rings sage.rings.function_field sage: M. = FunctionField(GaussianIntegers().fraction_field()) # optional - sage.rings.number_field - sage: M.has_coerce_map_from(L) # optional - sage.libs.pari sage.rings.function_field sage.rings.number_field + sage: M.has_coerce_map_from(L) # optional - sage.rings.finite_rings sage.rings.function_field sage.rings.number_field True Check that :trac:`31072` is fixed:: @@ -939,10 +939,10 @@ def valuation(self, prime): Note that classical valuations at finite places or the infinite place are always normalized such that the uniformizing element has valuation 1:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari sage.rings.function_field - sage: M. = FunctionField(K) # optional - sage.libs.pari sage.rings.function_field - sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari sage.rings.function_field - sage: v(x^3 - t) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: M. = FunctionField(K) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = M.valuation(x^3 - t) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v(x^3 - t) # optional - sage.rings.finite_rings sage.rings.function_field 1 However, if such a valuation comes out of a base change of the ground @@ -950,16 +950,16 @@ def valuation(self, prime): extension of ``v`` to ``L`` still has valuation 1 on `x^3 - t` but it has valuation ``1/3`` on its uniformizing element `x - w`:: - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(w^3 - t) # optional - sage.libs.pari sage.rings.function_field - sage: N. = FunctionField(L) # optional - sage.libs.pari sage.rings.function_field - sage: w = v.extension(N) # missing factorization, :trac:`16572` # optional - sage.libs.pari sage.rings.function_field + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(w^3 - t) # optional - sage.rings.finite_rings sage.rings.function_field + sage: N. = FunctionField(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = v.extension(N) # missing factorization, :trac:`16572` # optional - sage.rings.finite_rings sage.rings.function_field Traceback (most recent call last): ... NotImplementedError - sage: w(x^3 - t) # not tested # optional - sage.libs.pari sage.rings.function_field + sage: w(x^3 - t) # not tested # optional - sage.rings.finite_rings sage.rings.function_field 1 - sage: w(x - w) # not tested # optional - sage.libs.pari sage.rings.function_field + sage: w(x - w) # not tested # optional - sage.rings.finite_rings sage.rings.function_field 1/3 There are several ways to create valuations on extensions of rational @@ -989,9 +989,9 @@ def space_of_differentials(self): sage: K.space_of_differentials() # optional - sage.modules Space of differentials of Rational function field in t over Rational Field - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field - sage: L.space_of_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.space_of_differentials() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field Space of differentials of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ @@ -1013,9 +1013,9 @@ def space_of_holomorphic_differentials(self): From: Space of differentials of Rational function field in t over Rational Field To: Vector space of dimension 0 over Rational Field) - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field - sage: L.space_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.space_of_holomorphic_differentials() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field (Vector space of dimension 4 over Finite Field of size 5, Linear map: From: Vector space of dimension 4 over Finite Field of size 5 @@ -1040,9 +1040,9 @@ def basis_of_holomorphic_differentials(self): sage: K.basis_of_holomorphic_differentials() # optional - sage.modules [] - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field - sage: L.basis_of_holomorphic_differentials() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.basis_of_holomorphic_differentials() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field [((x/(x^3 + 4))*y) d(x), ((1/(x^3 + 4))*y) d(x), ((x/(x^3 + 4))*y^2) d(x), @@ -1067,9 +1067,9 @@ def divisor_group(self): sage: L.divisor_group() # optional - sage.modules sage.rings.function_field Divisor group of Function field in y defined by y^3 + (-t^3 + 1)/(t^3 - 2) - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari sage.rings.function_field - sage: L.divisor_group() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.divisor_group() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field Divisor group of Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) """ from .divisor import DivisorGroup @@ -1081,17 +1081,17 @@ def place_set(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.place_set() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.place_set() # optional - sage.rings.finite_rings Set of places of Rational function field in t over Finite Field of size 7 sage: K. = FunctionField(QQ) sage: K.place_set() Set of places of Rational function field in t over Rational Field - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field Set of places of Function field in y defined by y^2 + y + (x^2 + 1)/x """ from .place import PlaceSet @@ -1115,57 +1115,57 @@ def completion(self, place, name=None, prec=None, gen_name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p); m # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p); m # optional - sage.rings.finite_rings sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x, 10) # optional - sage.libs.pari sage.rings.function_field + sage: m(x, 10) # optional - sage.rings.finite_rings sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y, 10) # optional - sage.libs.pari sage.rings.function_field + sage: m(y, 10) # optional - sage.rings.finite_rings sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p); m # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p); m # optional - sage.rings.finite_rings sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x, 10) # optional - sage.libs.pari sage.rings.function_field + sage: m(x, 10) # optional - sage.rings.finite_rings sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + O(s^12) - sage: m(y, 10) # optional - sage.libs.pari sage.rings.function_field + sage: m(y, 10) # optional - sage.rings.finite_rings sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + O(s^9) - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: p = K.places_finite()[0]; p # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: p = K.places_finite()[0]; p # optional - sage.rings.finite_rings Place (x) - sage: m = K.completion(p); m # optional - sage.libs.pari + sage: m = K.completion(p); m # optional - sage.rings.finite_rings Completion map: From: Rational function field in x over Finite Field of size 2 To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(1/(x+1)) # optional - sage.libs.pari + sage: m(1/(x+1)) # optional - sage.rings.finite_rings 1 + s + s^2 + s^3 + s^4 + s^5 + s^6 + s^7 + s^8 + s^9 + s^10 + s^11 + s^12 + s^13 + s^14 + s^15 + s^16 + s^17 + s^18 + s^19 + O(s^20) - sage: p = K.place_infinite(); p # optional - sage.libs.pari + sage: p = K.place_infinite(); p # optional - sage.rings.finite_rings Place (1/x) - sage: m = K.completion(p); m # optional - sage.libs.pari + sage: m = K.completion(p); m # optional - sage.rings.finite_rings Completion map: From: Rational function field in x over Finite Field of size 2 To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x) # optional - sage.libs.pari + sage: m(x) # optional - sage.rings.finite_rings s^-1 + O(s^19) - sage: m = K.completion(p, prec=infinity); m # optional - sage.libs.pari + sage: m = K.completion(p, prec=infinity); m # optional - sage.rings.finite_rings Completion map: From: Rational function field in x over Finite Field of size 2 To: Lazy Laurent Series Ring in s over Finite Field of size 2 - sage: f = m(x); f # optional - sage.libs.pari + sage: f = m(x); f # optional - sage.rings.finite_rings s^-1 + ... - sage: f.coefficient(100) # optional - sage.libs.pari + sage: f.coefficient(100) # optional - sage.rings.finite_rings 0 sage: K. = FunctionField(QQ); _. = K[] @@ -1207,12 +1207,12 @@ def extension_constant_field(self, k): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: E = F.extension_constant_field(GF(2^4)) # optional - sage.libs.pari sage.rings.function_field - sage: E # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E = F.extension_constant_field(GF(2^4)) # optional - sage.rings.finite_rings sage.rings.function_field + sage: E # optional - sage.rings.finite_rings sage.rings.function_field Function field in y defined by y^2 + y + (x^2 + 1)/x over its base - sage: E.constant_base_field() # optional - sage.libs.pari sage.rings.function_field + sage: E.constant_base_field() # optional - sage.rings.finite_rings sage.rings.function_field Finite Field in z4 of size 2^4 """ from .extensions import ConstantFieldExtension diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index e9f058d38d8..3ecf29dfdee 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -474,9 +474,9 @@ def constant_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^5 - x) # optional - sage.libs.pari - sage: L.constant_field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^5 - x) # optional - sage.rings.finite_rings + sage: L.constant_field() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError @@ -614,28 +614,28 @@ def is_separable(self, base=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: L.is_separable() # optional - sage.rings.finite_rings False - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari - sage: M.is_separable() # optional - sage.libs.pari + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^3 - y) # optional - sage.rings.finite_rings + sage: M.is_separable() # optional - sage.rings.finite_rings True - sage: M.is_separable(K) # optional - sage.libs.pari + sage: M.is_separable(K) # optional - sage.rings.finite_rings False - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.rings.finite_rings + sage: L.is_separable() # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - 1) # optional - sage.libs.pari - sage: L.is_separable() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^5 - 1) # optional - sage.rings.finite_rings + sage: L.is_separable() # optional - sage.rings.finite_rings False """ @@ -798,14 +798,14 @@ def maximal_order_infinite(self): sage: L.maximal_order_infinite() Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: F.maximal_order_infinite() # optional - sage.rings.finite_rings Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.maximal_order_infinite() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: L.maximal_order_infinite() # optional - sage.rings.finite_rings Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ from .order import FunctionFieldMaximalOrderInfinite_polymod @@ -817,9 +817,9 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F.different() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: F.different() # optional - sage.rings.finite_rings 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) """ @@ -1062,12 +1062,12 @@ def _simple_model(self, name='v'): Check that this also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: M._simple_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^2 - y) # optional - sage.rings.finite_rings + sage: M._simple_model() # optional - sage.rings.finite_rings (Function field in v defined by v^4 + x, Function Field morphism: From: Function field in v defined by v^4 + x @@ -1082,12 +1082,12 @@ def _simple_model(self, name='v'): An example where the generator of the last extension does not generate the extension of the rational function field:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - 1) # optional - sage.libs.pari - sage: M._simple_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^3 - 1) # optional - sage.rings.finite_rings + sage: M._simple_model() # optional - sage.rings.finite_rings (Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1, Function Field morphism: From: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1 @@ -1222,10 +1222,10 @@ def simple_model(self, name=None): An example with higher degrees:: - sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - x) # optional - sage.libs.pari - sage: M.simple_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^5 - x); R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^3 - x) # optional - sage.rings.finite_rings + sage: M.simple_model() # optional - sage.rings.finite_rings (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3, Function Field morphism: From: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3 @@ -1240,10 +1240,10 @@ def simple_model(self, name=None): This also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x); R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: M.simple_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x); R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^2 - y) # optional - sage.rings.finite_rings + sage: M.simple_model() # optional - sage.rings.finite_rings (Function field in z defined by z^4 + x, Function Field morphism: From: Function field in z defined by z^4 + x To: Function field in z defined by z^2 + y @@ -1313,12 +1313,12 @@ def primitive_element(self): This also works for inseparable extensions:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(Z^2 - y) # optional - sage.libs.pari - sage: M.primitive_element() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(Z^2 - y) # optional - sage.rings.finite_rings + sage: M.primitive_element() # optional - sage.rings.finite_rings z """ N, f, t = self.simple_model() @@ -1354,10 +1354,10 @@ def separable_model(self, names=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3) # optional - sage.libs.pari - sage: L.separable_model(('t','w')) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3) # optional - sage.rings.finite_rings + sage: L.separable_model(('t','w')) # optional - sage.rings.finite_rings (Function field in t defined by t^3 + w^2, Function Field morphism: From: Function field in t defined by t^3 + w^2 @@ -1372,10 +1372,10 @@ def separable_model(self, names=None): This also works for non-integral polynomials:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2/x - x^2) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2/x - x^2) # optional - sage.rings.finite_rings + sage: L.separable_model() # optional - sage.rings.finite_rings (Function field in y_ defined by y_^3 + x_^2, Function Field morphism: From: Function field in y_ defined by y_^3 + x_^2 @@ -1390,13 +1390,13 @@ def separable_model(self, names=None): If the base field is not perfect this is only implemented in trivial cases:: - sage: k. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: k.is_perfect() # optional - sage.libs.pari + sage: k. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: k.is_perfect() # optional - sage.rings.finite_rings False - sage: K. = FunctionField(k) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - t) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari + sage: K. = FunctionField(k) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 - t) # optional - sage.rings.finite_rings + sage: L.separable_model() # optional - sage.rings.finite_rings (Function field in y defined by y^3 + t, Function Field endomorphism of Function field in y defined by y^3 + t Defn: y |--> y @@ -1408,9 +1408,9 @@ def separable_model(self, names=None): Some other cases for which a separable model could be constructed are not supported yet:: - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - t) # optional - sage.libs.pari - sage: L.separable_model() # optional - sage.libs.pari + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - t) # optional - sage.rings.finite_rings + sage: L.separable_model() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: constructing a separable model is only implemented for function fields over a perfect constant base field @@ -1433,12 +1433,12 @@ def separable_model(self, names=None): Check that this works for towers of inseparable extensions:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari - sage: M.separable_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^2 - y) # optional - sage.rings.finite_rings + sage: M.separable_model() # optional - sage.rings.finite_rings (Function field in z_ defined by z_ + x_^4, Function Field morphism: From: Function field in z_ defined by z_ + x_^4 @@ -1454,12 +1454,12 @@ def separable_model(self, names=None): Check that this also works if only the first extension is inseparable:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x) # optional - sage.libs.pari - sage: R. = L[] # optional - sage.libs.pari - sage: M. = L.extension(z^3 - y) # optional - sage.libs.pari - sage: M.separable_model() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(z^3 - y) # optional - sage.rings.finite_rings + sage: M.separable_model() # optional - sage.rings.finite_rings (Function field in z_ defined by z_ + x_^6, Function Field morphism: From: Function field in z_ defined by z_ + x_^6 To: Function field in z defined by z^3 + y @@ -1638,9 +1638,9 @@ def _inversion_isomorphism(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: F._inversion_isomorphism() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: F._inversion_isomorphism() # optional - sage.rings.finite_rings (Function field in s defined by s^3 + x^16 + x^14 + x^12, Composite map: From: Function field in s defined by s^3 + x^16 + x^14 + x^12 To: Function field in y defined by y^3 + x^6 + x^4 + x^2 @@ -1695,9 +1695,9 @@ def places_above(self, p): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: all(q.place_below() == p # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: all(q.place_below() == p # optional - sage.rings.finite_rings ....: for p in K.places() for q in F.places_above(p)) True @@ -1737,9 +1737,9 @@ def constant_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.libs.pari - sage: L.constant_field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # optional - sage.rings.finite_rings + sage: L.constant_field() # optional - sage.rings.finite_rings Finite Field of size 3 """ return self.exact_constant_field()[0] @@ -1754,17 +1754,17 @@ def exact_constant_field(self, name='t'): EXAMPLES:: - sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.libs.pari - sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible # optional - sage.libs.pari - sage: L. = K.extension(f) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)); _. = K[] # optional - sage.rings.finite_rings + sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible # optional - sage.rings.finite_rings + sage: L. = K.extension(f) # optional - sage.rings.finite_rings + sage: L.genus() # optional - sage.rings.finite_rings 0 - sage: L.exact_constant_field() # optional - sage.libs.pari + sage: L.exact_constant_field() # optional - sage.rings.finite_rings (Finite Field in t of size 3^2, Ring morphism: From: Finite Field in t of size 3^2 To: Function field in y defined by y^2 + 2*x*y + x^2 + 1 Defn: t |--> y + x) - sage: (y+x).divisor() # optional - sage.libs.pari + sage: (y+x).divisor() # optional - sage.rings.finite_rings 0 """ # A basis of the full constant field is obtained from @@ -1799,12 +1799,12 @@ def genus(self): EXAMPLES:: - sage: F. = GF(16) # optional - sage.libs.pari - sage: K. = FunctionField(F); K # optional - sage.libs.pari + sage: F. = GF(16) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F); K # optional - sage.rings.finite_rings Rational function field in x over Finite Field in a of size 2^4 - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L.genus() # optional - sage.rings.finite_rings 6 The genus is computed by the Hurwitz genus formula. @@ -1838,24 +1838,24 @@ def residue_field(self, place, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: R, fr_R, to_R = L.residue_field(p) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings + sage: R, fr_R, to_R = L.residue_field(p) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Finite Field of size 2 - sage: f = 1 + y # optional - sage.libs.pari - sage: f.valuation(p) # optional - sage.libs.pari + sage: f = 1 + y # optional - sage.rings.finite_rings + sage: f.valuation(p) # optional - sage.rings.finite_rings -1 - sage: to_R(f) # optional - sage.libs.pari + sage: to_R(f) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: ... - sage: (1+1/f).valuation(p) # optional - sage.libs.pari + sage: (1+1/f).valuation(p) # optional - sage.rings.finite_rings 0 - sage: to_R(1 + 1/f) # optional - sage.libs.pari + sage: to_R(1 + 1/f) # optional - sage.rings.finite_rings 1 - sage: [fr_R(e) for e in R] # optional - sage.libs.pari + sage: [fr_R(e) for e in R] # optional - sage.rings.finite_rings [0, 1] """ return place.residue_field(name=name) @@ -1909,23 +1909,23 @@ class FunctionField_global(FunctionField_simple): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings + sage: L # optional - sage.rings.finite_rings Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) The defining equation needs not be monic:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension((1 - x)*Y^7 - x^3) # optional - sage.libs.pari - sage: L.gaps() # long time (6s) # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension((1 - x)*Y^7 - x^3) # optional - sage.rings.finite_rings + sage: L.gaps() # long time (6s) # optional - sage.rings.finite_rings [1, 2, 3] or may define a trivial extension:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y-1) # optional - sage.libs.pari - sage: L.genus() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y-1) # optional - sage.rings.finite_rings + sage: L.genus() # optional - sage.rings.finite_rings 0 """ _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global') @@ -1936,9 +1936,9 @@ def __init__(self, polynomial, names): TESTS:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: TestSuite(L).run() # long time (7s) # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # long time (7s) # optional - sage.rings.finite_rings """ FunctionField_polymod.__init__(self, polynomial, names) @@ -1948,11 +1948,11 @@ def maximal_order(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: O.basis() # optional - sage.rings.finite_rings (1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y) """ from .order_polymod import FunctionFieldMaximalOrder_global @@ -1970,9 +1970,9 @@ def higher_derivation(self): EXAMPLES:: - sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.libs.pari - sage: L.higher_derivation() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(5)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # optional - sage.rings.finite_rings + sage: L.higher_derivation() # optional - sage.rings.finite_rings sage.modules Higher derivation map: From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3) @@ -1992,25 +1992,25 @@ def get_place(self, degree): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(Y^4 + Y - x^5) # optional - sage.libs.pari - sage: L.get_place(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^4 + Y - x^5) # optional - sage.rings.finite_rings + sage: L.get_place(1) # optional - sage.rings.finite_rings Place (x, y) - sage: L.get_place(2) # optional - sage.libs.pari + sage: L.get_place(2) # optional - sage.rings.finite_rings Place (x, y^2 + y + 1) - sage: L.get_place(3) # optional - sage.libs.pari + sage: L.get_place(3) # optional - sage.rings.finite_rings Place (x^3 + x^2 + 1, y + x^2 + x) - sage: L.get_place(4) # optional - sage.libs.pari + sage: L.get_place(4) # optional - sage.rings.finite_rings Place (x + 1, x^5 + 1) - sage: L.get_place(5) # optional - sage.libs.pari + sage: L.get_place(5) # optional - sage.rings.finite_rings Place (x^5 + x^3 + x^2 + x + 1, y + x^4 + 1) - sage: L.get_place(6) # optional - sage.libs.pari + sage: L.get_place(6) # optional - sage.rings.finite_rings Place (x^3 + x^2 + 1, y^2 + y + x^2) - sage: L.get_place(7) # optional - sage.libs.pari + sage: L.get_place(7) # optional - sage.rings.finite_rings Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x) - sage: L.get_place(8) # optional - sage.libs.pari + sage: L.get_place(8) # optional - sage.rings.finite_rings """ for p in self._places_finite(degree): @@ -2031,11 +2031,11 @@ def places(self, degree=1): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L.places(1) # optional - sage.rings.finite_rings [Place (1/x, 1/x^4*y^3), Place (x, y), Place (x, y + 1)] """ return self.places_infinite(degree) + self.places_finite(degree) @@ -2050,11 +2050,11 @@ def places_finite(self, degree=1): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places_finite(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L.places_finite(1) # optional - sage.rings.finite_rings [Place (x, y), Place (x, y + 1)] """ return list(self._places_finite(degree)) @@ -2069,11 +2069,11 @@ def _places_finite(self, degree): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L._places_finite(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L._places_finite(1) # optional - sage.rings.finite_rings """ O = self.maximal_order() @@ -2098,11 +2098,11 @@ def places_infinite(self, degree=1): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L.places_infinite(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L.places_infinite(1) # optional - sage.rings.finite_rings [Place (1/x, 1/x^4*y^3)] """ return list(self._places_infinite(degree)) @@ -2117,11 +2117,11 @@ def _places_infinite(self, degree): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: L. = K.extension(t^4 + t - x^5) # optional - sage.libs.pari - sage: L._places_infinite(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: L. = K.extension(t^4 + t - x^5) # optional - sage.rings.finite_rings + sage: L._places_infinite(1) # optional - sage.rings.finite_rings """ Oinf = self.maximal_order_infinite() @@ -2139,9 +2139,9 @@ def gaps(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.gaps() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.rings.finite_rings + sage: L.gaps() # optional - sage.rings.finite_rings sage.modules [1, 2, 3] """ return self._weierstrass_places()[1] @@ -2152,9 +2152,9 @@ def weierstrass_places(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: L.weierstrass_places() # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.rings.finite_rings + sage: L.weierstrass_places() # optional - sage.rings.finite_rings sage.modules [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y), @@ -2176,9 +2176,9 @@ def _weierstrass_places(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.libs.pari sage.modules + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.rings.finite_rings + sage: len(L.weierstrass_places()) # indirect doctest # optional - sage.rings.finite_rings sage.modules 10 This method implements Algorithm 30 in [Hes2002b]_. @@ -2224,9 +2224,9 @@ def L_polynomial(self, name='t'): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: F.L_polynomial() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: F.L_polynomial() # optional - sage.rings.finite_rings 2*t^2 + t + 1 """ from sage.rings.integer_ring import ZZ @@ -2256,11 +2256,11 @@ def number_of_rational_places(self, r=1): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: F.number_of_rational_places() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: F.number_of_rational_places() # optional - sage.rings.finite_rings 4 - sage: [F.number_of_rational_places(r) for r in [1..10]] # optional - sage.libs.pari + sage: [F.number_of_rational_places(r) for r in [1..10]] # optional - sage.rings.finite_rings [4, 8, 4, 16, 44, 56, 116, 288, 508, 968] """ from sage.rings.integer_ring import IntegerRing @@ -2351,10 +2351,10 @@ def _maximal_order_basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.libs.pari - sage: F._maximal_order_basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18) # optional - sage.rings.finite_rings + sage: F._maximal_order_basis() # optional - sage.rings.finite_rings [1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y] The basis of the maximal order *always* starts with 1. This is assumed @@ -2449,9 +2449,9 @@ def equation_order(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.equation_order() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: F.equation_order() # optional - sage.rings.finite_rings Order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) @@ -2475,11 +2475,11 @@ def primitive_integal_element_infinite(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: b = F.primitive_integal_element_infinite(); b # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: b = F.primitive_integal_element_infinite(); b # optional - sage.rings.finite_rings 1/x^2*y - sage: b.minimal_polynomial('t') # optional - sage.libs.pari + sage: b.minimal_polynomial('t') # optional - sage.rings.finite_rings t^3 + (x^4 + x^2 + 1)/x^4 """ f = self.polynomial() @@ -2502,9 +2502,9 @@ def equation_order_infinite(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.equation_order_infinite() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: F.equation_order_infinite() # optional - sage.rings.finite_rings Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2 sage: K. = FunctionField(QQ); R. = PolynomialRing(K) diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index ada2d9fb362..9155e9539b6 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -32,11 +32,11 @@ class RationalFunctionField(FunctionField): EXAMPLES:: - sage: K. = FunctionField(GF(3)); K # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)); K # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 3 - sage: K.gen() # optional - sage.libs.pari + sage: K.gen() # optional - sage.rings.finite_rings t - sage: 1/t + t^3 + 5 # optional - sage.libs.pari + sage: 1/t + t^3 + 5 # optional - sage.rings.finite_rings (t^4 + 2*t + 1)/t sage: K. = FunctionField(QQ); K @@ -49,14 +49,14 @@ class RationalFunctionField(FunctionField): There are various ways to get at the underlying fields and rings associated to a rational function field:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.base_field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.base_field() # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 7 - sage: K.field() # optional - sage.libs.pari + sage: K.field() # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 - sage: K.constant_field() # optional - sage.libs.pari + sage: K.constant_field() # optional - sage.rings.finite_rings Finite Field of size 7 - sage: K.maximal_order() # optional - sage.libs.pari + sage: K.maximal_order() # optional - sage.rings.finite_rings Maximal order of Rational function field in t over Finite Field of size 7 sage: K. = FunctionField(QQ) @@ -321,10 +321,10 @@ def _to_bivariate_polynomial(self, f): EXAMPLES:: - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari - sage: R._to_bivariate_polynomial(f) # optional - sage.libs.pari + sage: R. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.rings.finite_rings + sage: R._to_bivariate_polynomial(f) # optional - sage.rings.finite_rings (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) """ v = f.list() @@ -356,34 +356,34 @@ def _factor_univariate_polynomial(self, f, proof=None): We do a factorization over a finite prime field:: - sage: R. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.libs.pari - sage: f.factor() # optional - sage.libs.pari + sage: R. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t) - sage: f.factor().prod() == f # optional - sage.libs.pari + sage: f.factor().prod() == f # optional - sage.rings.finite_rings True Factoring over a function field over a non-prime finite field:: - sage: k. = GF(9) # optional - sage.libs.pari - sage: R. = FunctionField(k) # optional - sage.libs.pari - sage: S. = R[] # optional - sage.libs.pari - sage: f = (1/t)*(X^3 - a*t^3) # optional - sage.libs.pari - sage: f.factor() # optional - sage.libs.pari + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: R. = FunctionField(k) # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: f = (1/t)*(X^3 - a*t^3) # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings (1/t) * (X + (a + 2)*t)^3 - sage: f.factor().prod() == f # optional - sage.libs.pari + sage: f.factor().prod() == f # optional - sage.rings.finite_rings True Factoring over a function field over a tower of finite fields:: - sage: k. = GF(4) # optional - sage.libs.pari - sage: R. = k[] # optional - sage.libs.pari - sage: l. = k.extension(b^2 + b + a) # optional - sage.libs.pari - sage: K. = FunctionField(l) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: F = t*x # optional - sage.libs.pari - sage: F.factor(proof=False) # optional - sage.libs.pari + sage: k. = GF(4) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: l. = k.extension(b^2 + b + a) # optional - sage.rings.finite_rings + sage: K. = FunctionField(l) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: F = t*x # optional - sage.rings.finite_rings + sage: F.factor(proof=False) # optional - sage.rings.finite_rings (x) * t """ @@ -607,8 +607,8 @@ def base_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.base_field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.base_field() # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 7 """ return self @@ -634,24 +634,24 @@ def hom(self, im_gens, base_morphism=None): We make a map from a rational function field to itself:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.hom((x^4 + 2)/x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.hom((x^4 + 2)/x) # optional - sage.rings.finite_rings Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> (x^4 + 2)/x We construct a map from a rational function field into a non-rational extension field:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field - sage: f = K.hom(y^2 + y + 2); f # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = K.hom(y^2 + y + 2); f # optional - sage.rings.finite_rings sage.rings.function_field Function Field morphism: From: Rational function field in x over Finite Field of size 7 To: Function field in y defined by y^3 + 6*x^3 + x Defn: x |--> y^2 + y + 2 - sage: f(x) # optional - sage.libs.pari sage.rings.function_field + sage: f(x) # optional - sage.rings.finite_rings sage.rings.function_field y^2 + y + 2 - sage: f(x^2) # optional - sage.libs.pari sage.rings.function_field + sage: f(x^2) # optional - sage.rings.finite_rings sage.rings.function_field 5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4 """ if isinstance(im_gens, CategoryObject): @@ -674,8 +674,8 @@ def field(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: K.field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: K.field() # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 .. SEEALSO:: @@ -827,12 +827,12 @@ def residue_field(self, place, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: p = F.places_finite(2)[0] # optional - sage.libs.pari - sage: R, fr_R, to_R = F.residue_field(p) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: p = F.places_finite(2)[0] # optional - sage.rings.finite_rings + sage: R, fr_R, to_R = F.residue_field(p) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Finite Field in z2 of size 5^2 - sage: to_R(x) in R # optional - sage.libs.pari + sage: to_R(x) in R # optional - sage.rings.finite_rings True """ return place.residue_field(name=name) @@ -878,8 +878,8 @@ def places(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.places() # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: F.places() # optional - sage.rings.finite_rings [Place (1/x), Place (x), Place (x + 1), @@ -902,8 +902,8 @@ def places_finite(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.places_finite() # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: F.places_finite() # optional - sage.rings.finite_rings [Place (x), Place (x + 1), Place (x + 2), Place (x + 3), Place (x + 4)] """ return list(self._places_finite(degree)) @@ -918,8 +918,8 @@ def _places_finite(self, degree=1): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F._places_finite() # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: F._places_finite() # optional - sage.rings.finite_rings """ O = self.maximal_order() @@ -937,8 +937,8 @@ def place_infinite(self): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: F.place_infinite() # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: F.place_infinite() # optional - sage.rings.finite_rings Place (1/x) """ return self.maximal_order_infinite().prime_ideal().place() @@ -953,17 +953,17 @@ def get_place(self, degree): EXAMPLES:: - sage: F. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(F) # optional - sage.libs.pari - sage: K.get_place(1) # optional - sage.libs.pari + sage: F. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(F) # optional - sage.rings.finite_rings + sage: K.get_place(1) # optional - sage.rings.finite_rings Place (x) - sage: K.get_place(2) # optional - sage.libs.pari + sage: K.get_place(2) # optional - sage.rings.finite_rings Place (x^2 + x + 1) - sage: K.get_place(3) # optional - sage.libs.pari + sage: K.get_place(3) # optional - sage.rings.finite_rings Place (x^3 + x + 1) - sage: K.get_place(4) # optional - sage.libs.pari + sage: K.get_place(4) # optional - sage.rings.finite_rings Place (x^4 + x + 1) - sage: K.get_place(5) # optional - sage.libs.pari + sage: K.get_place(5) # optional - sage.rings.finite_rings Place (x^5 + x^2 + 1) """ @@ -981,11 +981,11 @@ def higher_derivation(self): EXAMPLES:: - sage: F. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: d = F.higher_derivation() # optional - sage.libs.pari - sage: [d(x^5,i) for i in range(10)] # optional - sage.libs.pari + sage: F. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: d = F.higher_derivation() # optional - sage.rings.finite_rings + sage: [d(x^5,i) for i in range(10)] # optional - sage.rings.finite_rings [x^5, 0, 0, 0, 0, 1, 0, 0, 0, 0] - sage: [d(x^7,i) for i in range(10)] # optional - sage.libs.pari + sage: [d(x^7,i) for i in range(10)] # optional - sage.rings.finite_rings [x^7, 2*x^6, x^5, 0, 0, x^2, 2*x, 1, 0, 0] """ from .derivations_polymod import RationalFunctionFieldHigherDerivation_global diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 534a07ee03e..8d203e9f019 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -35,37 +35,37 @@ Ideals in the maximal order of a global function field:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I^2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I^2 # optional - sage.rings.finite_rings sage.rings.function_field Ideal (x) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I # optional - sage.libs.pari sage.rings.function_field + sage: ~I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1/x*y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: ~I * I # optional - sage.libs.pari sage.rings.function_field + sage: ~I * I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J = O.ideal(x + y) * I # optional - sage.libs.pari sage.rings.function_field - sage: J.factor() # optional - sage.libs.pari sage.rings.function_field + sage: J = O.ideal(x + y) * I # optional - sage.rings.finite_rings sage.rings.function_field + sage: J.factor() # optional - sage.rings.finite_rings sage.rings.function_field (Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x)^2 * (Ideal (x^3 + x + 1, y + x) of Maximal order of Function field in y defined by y^2 + x^3*y + x) Ideals in the maximal infinite order of a global function field:: - sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field - sage: I + I == I # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I + I == I # optional - sage.rings.finite_rings sage.rings.function_field True - sage: I^2 # optional - sage.libs.pari sage.rings.function_field + sage: I^2 # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1/x^4*y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I # optional - sage.libs.pari sage.rings.function_field + sage: ~I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: ~I * I # optional - sage.libs.pari sage.rings.function_field + sage: ~I * I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: I.factor() # optional - sage.libs.pari sage.rings.function_field + sage: I.factor() # optional - sage.rings.finite_rings sage.rings.function_field (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^4 AUTHORS: @@ -113,9 +113,9 @@ class FunctionFieldIdeal(Element): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.equation_order() # optional - sage.libs.pari - sage: O.ideal(x^3 + 1) # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.equation_order() # optional - sage.rings.finite_rings + sage: O.ideal(x^3 + 1) # optional - sage.rings.finite_rings Ideal (x^3 + 1) of Maximal order of Rational function field in x over Finite Field of size 7 """ def __init__(self, ring): @@ -124,10 +124,10 @@ def __init__(self, ring): TESTS:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3 + 1) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.equation_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^3 + 1) # optional - sage.rings.finite_rings + sage: TestSuite(I).run() # optional - sage.rings.finite_rings """ Element.__init__(self, ring.ideal_monoid()) self._ring = ring @@ -139,11 +139,11 @@ def _repr_short(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field - sage: I._repr_short() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3^2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I._repr_short() # optional - sage.rings.finite_rings sage.rings.function_field '(1/x^4*y^2)' """ if self.is_zero(): @@ -163,41 +163,41 @@ def _repr_(self): Ideal (1/(x + 1)) of Maximal order of Rational function field in x over Rational Field sage: K. = FunctionField(QQ); R. = K[] - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.ideal(x^2 + 1) # optional - sage.libs.pari sage.rings.function_field + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.ideal(x^2 + 1) # optional - sage.rings.finite_rings sage.rings.function_field Ideal (x^2 + 1) of Order in Function field in y defined by y^2 - x^3 - 1 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y); I # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y); I # optional - sage.libs.pari sage.rings.function_field + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.rings.finite_rings + sage: I # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf.ideal(1/y) # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: Oinf.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf.ideal(1/y) # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -212,11 +212,11 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: latex(I) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: latex(I) # optional - sage.rings.finite_rings sage.rings.function_field \left(y\right) """ return '\\left(' + ', '.join(latex(g) for g in self.gens_reduced()) + '\\right)' @@ -231,10 +231,10 @@ def _div_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3 + 1) # optional - sage.libs.pari - sage: I / I # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.equation_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^3 + 1) # optional - sage.rings.finite_rings + sage: I / I # optional - sage.rings.finite_rings Ideal (1) of Maximal order of Rational function field in x over Finite Field of size 7 """ @@ -255,10 +255,10 @@ def gens_reduced(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.libs.pari - sage: I.gens_reduced() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.equation_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.rings.finite_rings + sage: I.gens_reduced() # optional - sage.rings.finite_rings (x,) """ gens = self.gens() @@ -277,10 +277,10 @@ def ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.equation_order() # optional - sage.libs.pari - sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.libs.pari - sage: I.ring() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.equation_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, x^2, x^2 + x) # optional - sage.rings.finite_rings + sage: I.ring() # optional - sage.rings.finite_rings Maximal order of Rational function field in x over Finite Field of size 7 """ return self._ring @@ -306,63 +306,63 @@ def place(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: I.place() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: I.place() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: not a prime ideal - sage: I = O.ideal(x^3 + x + 1) # optional - sage.libs.pari - sage: I.place() # optional - sage.libs.pari + sage: I = O.ideal(x^3 + x + 1) # optional - sage.rings.finite_rings + sage: I.place() # optional - sage.rings.finite_rings Place (x^3 + x + 1) - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari - sage: p = I.factor()[0][0] # optional - sage.libs.pari - sage: p.place() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.rings.finite_rings + sage: p = I.factor()[0][0] # optional - sage.rings.finite_rings + sage: p.place() # optional - sage.rings.finite_rings Place (1/x) - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: [f.place() for f,_ in I.factor()] # optional - sage.rings.finite_rings sage.rings.function_field [Place (x, (1/(x^3 + x^2 + x))*y^2), Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2)] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: [f.place() for f,_ in I.factor()] # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: [f.place() for f,_ in I.factor()] # optional - sage.rings.finite_rings sage.rings.function_field [Place (x, x*y), Place (x + 1, x*y)] - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari sage.rings.function_field - sage: I.factor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.factor() # optional - sage.rings.finite_rings sage.rings.function_field (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] # optional - sage.libs.pari sage.rings.function_field - sage: J.is_prime() # optional - sage.libs.pari sage.rings.function_field + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: J.is_prime() # optional - sage.rings.finite_rings sage.rings.function_field True - sage: J.place() # optional - sage.libs.pari sage.rings.function_field + sage: J.place() # optional - sage.rings.finite_rings sage.rings.function_field Place (1/x, 1/x^3*y^2) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari sage.rings.function_field - sage: I.factor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.factor() # optional - sage.rings.finite_rings sage.rings.function_field (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] # optional - sage.libs.pari sage.rings.function_field - sage: J.is_prime() # optional - sage.libs.pari sage.rings.function_field + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: J.is_prime() # optional - sage.rings.finite_rings sage.rings.function_field True - sage: J.place() # optional - sage.libs.pari sage.rings.function_field + sage: J.place() # optional - sage.rings.finite_rings sage.rings.function_field Place (1/x, 1/x*y) """ if not self.is_prime(): @@ -380,32 +380,32 @@ def factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3*(x + 1)^2) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^3*(x + 1)^2) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (x) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^3 * (Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^2 - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field in z2 of size 2^2)^2 - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I == I.factor().prod() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I == I.factor().prod() # optional - sage.rings.finite_rings sage.rings.function_field True - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: f= 1/x # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(f) # optional - sage.libs.pari sage.rings.function_field - sage: I.factor() # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: f= 1/x # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(f) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.factor() # optional - sage.rings.finite_rings sage.rings.function_field (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2) * (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order @@ -434,42 +434,42 @@ def divisor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.rings.finite_rings + sage: I.divisor() # optional - sage.rings.finite_rings Place (x) + 2*Place (x + 1) - Place (x + z2) - Place (x + z2 + 1) - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari - sage: I.divisor() # optional - sage.libs.pari + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.rings.finite_rings + sage: I.divisor() # optional - sage.rings.finite_rings 2*Place (1/x) - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(T^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field 2*Place (x, (1/(x^3 + x^2 + x))*y^2) + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2) - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field -2*Place (1/x, 1/x^4*y^2 + 1/x^2*y + 1) - 2*Place (1/x, 1/x^2*y + 1) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field - Place (x, x*y) + 2*Place (x + 1, x*y) - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: I = Oinf.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = Oinf.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field - Place (1/x, 1/x*y) """ from .divisor import divisor @@ -487,23 +487,23 @@ def divisor_of_zeros(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari - sage: I.divisor_of_zeros() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.rings.finite_rings + sage: I.divisor_of_zeros() # optional - sage.rings.finite_rings Place (x) + 2*Place (x + 1) - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari - sage: I.divisor_of_zeros() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.rings.finite_rings + sage: I.divisor_of_zeros() # optional - sage.rings.finite_rings 2*Place (1/x) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor_of_zeros() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor_of_zeros() # optional - sage.rings.finite_rings sage.rings.function_field 2*Place (x + 1, x*y) """ from .divisor import divisor @@ -521,23 +521,23 @@ def divisor_of_poles(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.libs.pari - sage: I.divisor_of_poles() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x*(x + 1)^2/(x^2 + x + 1)) # optional - sage.rings.finite_rings + sage: I.divisor_of_poles() # optional - sage.rings.finite_rings Place (x + z2) + Place (x + z2 + 1) - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.libs.pari - sage: I.divisor_of_poles() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x + 1)/(x^3 + 1)) # optional - sage.rings.finite_rings + sage: I.divisor_of_poles() # optional - sage.rings.finite_rings 0 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(y) # optional - sage.libs.pari sage.rings.function_field - sage: I.divisor_of_poles() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I.divisor_of_poles() # optional - sage.rings.finite_rings sage.rings.function_field Place (x, x*y) """ from .divisor import divisor @@ -901,16 +901,16 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.rings.function_field + sage: y in I # optional - sage.rings.finite_rings sage.rings.function_field True - sage: y/x in I # optional - sage.libs.pari sage.rings.function_field + sage: y/x in I # optional - sage.rings.finite_rings sage.rings.function_field False - sage: y^2 - 2 in I # optional - sage.libs.pari sage.rings.function_field + sage: y^2 - 2 in I # optional - sage.rings.finite_rings sage.rings.function_field True """ return self._structure[2](x) in self._module @@ -921,11 +921,11 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari sage.rings.function_field - sage: d = {I: 2} # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.rings.finite_rings sage.rings.function_field + sage: d = {I: 2} # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field """ return hash((self._ring,self._module)) @@ -939,11 +939,11 @@ def __eq__(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.libs.pari sage.rings.function_field - sage: I == I + I # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]) # optional - sage.rings.finite_rings sage.rings.function_field + sage: I == I + I # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field True """ if not isinstance(other, FunctionFieldIdeal_module): @@ -967,21 +967,21 @@ def module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: O = K.maximal_order(); O # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order(); O # optional - sage.rings.finite_rings Maximal order of Rational function field in x over Finite Field of size 7 - sage: K.polynomial_ring() # optional - sage.libs.pari + sage: K.polynomial_ring() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7 - sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: I = O.ideal([x^2 + 1, x*(x^2+1)]) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^2 + 1,) - sage: I.module() # optional - sage.libs.pari + sage: I.module() # optional - sage.rings.finite_rings Free module of degree 1 and rank 1 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [x^2 + 1] - sage: V, from_V, to_V = K.vector_space(); V # optional - sage.libs.pari + sage: V, from_V, to_V = K.vector_space(); V # optional - sage.rings.finite_rings Vector space of dimension 1 over Rational function field in x over Finite Field of size 7 - sage: I.module().is_submodule(V) # optional - sage.libs.pari + sage: I.module().is_submodule(V) # optional - sage.rings.finite_rings True """ return self._module @@ -997,9 +997,9 @@ class IdealMonoid(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid(); M # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid(); M # optional - sage.rings.finite_rings Monoid of ideals of Maximal order of Rational function field in x over Finite Field of size 2 """ @@ -1009,10 +1009,10 @@ def __init__(self, R): TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid() # optional - sage.libs.pari - sage: TestSuite(M).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid() # optional - sage.rings.finite_rings + sage: TestSuite(M).run() # optional - sage.rings.finite_rings """ self.Element = R._ideal_class Parent.__init__(self, category = Monoids()) @@ -1026,9 +1026,9 @@ def _repr_(self): TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid(); M._repr_() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid(); M._repr_() # optional - sage.rings.finite_rings 'Monoid of ideals of Maximal order of Rational function field in x over Finite Field of size 2' """ return "Monoid of ideals of %s" % self.__R @@ -1039,9 +1039,9 @@ def ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid(); M.ring() is O # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid(); M.ring() is O # optional - sage.rings.finite_rings True """ return self.__R @@ -1052,12 +1052,12 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid() # optional - sage.libs.pari - sage: M(x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid() # optional - sage.rings.finite_rings + sage: M(x) # optional - sage.rings.finite_rings Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 - sage: M([x-4, 1/x]) # optional - sage.libs.pari + sage: M([x-4, 1/x]) # optional - sage.rings.finite_rings Ideal (1/x) of Maximal order of Rational function field in x over Finite Field of size 2 """ try: # x is an ideal @@ -1072,12 +1072,12 @@ def _coerce_map_from_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid() # optional - sage.libs.pari - sage: M.has_coerce_map_from(O) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid() # optional - sage.rings.finite_rings + sage: M.has_coerce_map_from(O) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.has_coerce_map_from(O.ideal_monoid()) # optional - sage.libs.pari + sage: M.has_coerce_map_from(O.ideal_monoid()) # optional - sage.rings.finite_rings True """ if isinstance(x, IdealMonoid): @@ -1091,10 +1091,10 @@ def _an_element_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: M = O.ideal_monoid() # optional - sage.libs.pari - sage: M.an_element() # indirect doctest; random # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: M = O.ideal_monoid() # optional - sage.rings.finite_rings + sage: M.an_element() # indirect doctest; random # optional - sage.rings.finite_rings Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 """ diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index fae17dba8f8..671a20fb434 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -36,10 +36,10 @@ class FunctionFieldIdeal_polymod(FunctionFieldIdeal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.ideal(y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.ideal(y) # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x """ def __init__(self, ring, hnf, denominator=1): @@ -48,11 +48,11 @@ def __init__(self, ring, hnf, denominator=1): TESTS:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: TestSuite(I).run() # optional - sage.rings.finite_rings """ FunctionFieldIdeal.__init__(self, ring) @@ -88,29 +88,29 @@ def __bool__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y); I # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: I.is_zero() # optional - sage.libs.pari + sage: I.is_zero() # optional - sage.rings.finite_rings False - sage: J = 0*I; J # optional - sage.libs.pari + sage: J = 0*I; J # optional - sage.rings.finite_rings Zero ideal of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: J.is_zero() # optional - sage.libs.pari + sage: J.is_zero() # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(2)); _.=K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _.=K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y); I # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I.is_zero() # optional - sage.libs.pari + sage: I.is_zero() # optional - sage.rings.finite_rings False - sage: J = 0*I; J # optional - sage.libs.pari + sage: J = 0*I; J # optional - sage.rings.finite_rings Zero ideal of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: J.is_zero() # optional - sage.libs.pari + sage: J.is_zero() # optional - sage.rings.finite_rings True """ return self._hnf.nrows() != 0 @@ -123,17 +123,17 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: { I: 2 }[I] == 2 # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(1/y) # optional - sage.rings.finite_rings + sage: { I: 2 }[I] == 2 # optional - sage.rings.finite_rings True - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: { I: 2 }[I] == 2 # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(1/y) # optional - sage.rings.finite_rings + sage: { I: 2 }[I] == 2 # optional - sage.rings.finite_rings True """ return hash((self._ring, self._hnf, self._denominator)) @@ -144,30 +144,30 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal([y]); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal([y]); I # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: x * y in I # optional - sage.libs.pari + sage: x * y in I # optional - sage.rings.finite_rings True - sage: y / x in I # optional - sage.libs.pari + sage: y / x in I # optional - sage.rings.finite_rings False - sage: y^2 - 2 in I # optional - sage.libs.pari + sage: y^2 - 2 in I # optional - sage.rings.finite_rings False - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal([y]); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal([y]); I # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: x * y in I # optional - sage.libs.pari + sage: x * y in I # optional - sage.rings.finite_rings True - sage: y / x in I # optional - sage.libs.pari + sage: y / x in I # optional - sage.rings.finite_rings False - sage: y^2 - 2 in I # optional - sage.libs.pari + sage: y^2 - 2 in I # optional - sage.rings.finite_rings False sage: K. = FunctionField(QQ); _. = K[] @@ -213,30 +213,30 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: ~I # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: ~I # optional - sage.rings.finite_rings Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I^(-1) # optional - sage.libs.pari + sage: I^(-1) # optional - sage.rings.finite_rings Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: ~I * I # optional - sage.libs.pari + sage: ~I * I # optional - sage.rings.finite_rings Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: ~I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: ~I # optional - sage.rings.finite_rings Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: I^(-1) # optional - sage.libs.pari + sage: I^(-1) # optional - sage.rings.finite_rings Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I * I # optional - sage.libs.pari + sage: ~I * I # optional - sage.rings.finite_rings Ideal (1) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x :: @@ -285,28 +285,28 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I == I + I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(1/y) # optional - sage.rings.finite_rings + sage: I == I + I # optional - sage.rings.finite_rings True - sage: I == I * I # optional - sage.libs.pari + sage: I == I * I # optional - sage.rings.finite_rings False :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I == I + I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(1/y) # optional - sage.rings.finite_rings + sage: I == I + I # optional - sage.rings.finite_rings True - sage: I == I * I # optional - sage.libs.pari + sage: I == I * I # optional - sage.rings.finite_rings False - sage: I < I * I # optional - sage.libs.pari + sage: I < I * I # optional - sage.rings.finite_rings True - sage: I > I * I # optional - sage.libs.pari + sage: I > I * I # optional - sage.rings.finite_rings False """ return richcmp((self._denominator, self._hnf), (other._denominator, other._hnf), op) @@ -317,19 +317,19 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I + J # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I + J # optional - sage.rings.finite_rings Ideal (1, y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ ds = self._denominator @@ -344,20 +344,20 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I * J # optional - sage.rings.finite_rings Ideal (x^4 + x^2 + x, x*y + x^2) of Maximal order of Function field in y defined by y^2 + x^3*y + x - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I * J # optional - sage.rings.finite_rings Ideal ((x + 1)*y + (x^2 + 1)/x) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -395,19 +395,19 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: x * I == I * J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x) # optional - sage.rings.finite_rings + sage: x * I == I * J # optional - sage.rings.finite_rings True - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: x * I == I * J # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x) # optional - sage.rings.finite_rings + sage: x * I == I * J # optional - sage.rings.finite_rings True """ from sage.modules.free_module_element import vector @@ -435,12 +435,12 @@ def intersect(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: J = O.ideal(x) # optional - sage.libs.pari - sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x) # optional - sage.rings.finite_rings + sage: I.intersect(J) == I * J * (I + J)^-1 # optional - sage.rings.finite_rings True """ @@ -480,10 +480,10 @@ def hnf(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y*(y+1)); I.hnf() # optional - sage.rings.finite_rings [x^6 + x^3 0] [ x^3 + 1 1] @@ -504,13 +504,13 @@ def denominator(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y/(y+1)) # optional - sage.libs.pari - sage: d = I.denominator(); d # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y/(y+1)) # optional - sage.rings.finite_rings + sage: d = I.denominator(); d # optional - sage.rings.finite_rings x^3 - sage: d in O # optional - sage.libs.pari + sage: d in O # optional - sage.rings.finite_rings True :: @@ -534,11 +534,11 @@ def module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.module() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.module() # optional - sage.rings.finite_rings Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -558,17 +558,17 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens_over_base() # optional - sage.rings.finite_rings (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens_over_base() # optional - sage.rings.finite_rings (x^3 + 1, y + x) """ gens, d = self._gens_over_base @@ -582,11 +582,11 @@ def _gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(1/y) # optional - sage.libs.pari - sage: I._gens_over_base # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(1/y) # optional - sage.rings.finite_rings + sage: I._gens_over_base # optional - sage.rings.finite_rings ([x, y], x) """ gens = [] @@ -603,17 +603,17 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^3 + 1, y + x) """ return self.gens_over_base() @@ -628,11 +628,11 @@ def basis_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.denominator() * I.basis_matrix() == I.hnf() # optional - sage.rings.finite_rings True """ d = self.denominator() @@ -648,24 +648,24 @@ def is_integral(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.is_integral() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.is_integral() # optional - sage.rings.finite_rings False - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.is_integral() # optional - sage.libs.pari + sage: J = I.denominator() * I # optional - sage.rings.finite_rings + sage: J.is_integral() # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.is_integral() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.is_integral() # optional - sage.rings.finite_rings False - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.is_integral() # optional - sage.libs.pari + sage: J = I.denominator() * I # optional - sage.rings.finite_rings + sage: J.is_integral() # optional - sage.rings.finite_rings True sage: K. = FunctionField(QQ); _. = PolynomialRing(K) @@ -688,29 +688,29 @@ def ideal_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.ideal_below() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.ideal_below() # optional - sage.libs.pari + sage: J = I.denominator() * I # optional - sage.rings.finite_rings + sage: J.ideal_below() # optional - sage.rings.finite_rings Ideal (x^3 + x^2 + x) of Maximal order of Rational function field in x over Finite Field of size 2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, 1/y) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, 1/y) # optional - sage.rings.finite_rings + sage: I.ideal_below() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: not an integral ideal - sage: J = I.denominator() * I # optional - sage.libs.pari - sage: J.ideal_below() # optional - sage.libs.pari + sage: J = I.denominator() * I # optional - sage.rings.finite_rings + sage: J.ideal_below() # optional - sage.rings.finite_rings Ideal (x^3 + x) of Maximal order of Rational function field in x over Finite Field of size 2 @@ -754,38 +754,38 @@ def norm(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: i1 = O.ideal(x) # optional - sage.libs.pari - sage: i2 = O.ideal(y) # optional - sage.libs.pari - sage: i3 = i1 * i2 # optional - sage.libs.pari - sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: i1 = O.ideal(x) # optional - sage.rings.finite_rings + sage: i2 = O.ideal(y) # optional - sage.rings.finite_rings + sage: i3 = i1 * i2 # optional - sage.rings.finite_rings + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.rings.finite_rings True - sage: i1.norm() # optional - sage.libs.pari + sage: i1.norm() # optional - sage.rings.finite_rings x^3 - sage: i1.norm() == x ** F.degree() # optional - sage.libs.pari + sage: i1.norm() == x ** F.degree() # optional - sage.rings.finite_rings True - sage: i2.norm() # optional - sage.libs.pari + sage: i2.norm() # optional - sage.rings.finite_rings x^6 + x^4 + x^2 - sage: i2.norm() == y.norm() # optional - sage.libs.pari + sage: i2.norm() == y.norm() # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: i1 = O.ideal(x) # optional - sage.libs.pari - sage: i2 = O.ideal(y) # optional - sage.libs.pari - sage: i3 = i1 * i2 # optional - sage.libs.pari - sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: i1 = O.ideal(x) # optional - sage.rings.finite_rings + sage: i2 = O.ideal(y) # optional - sage.rings.finite_rings + sage: i3 = i1 * i2 # optional - sage.rings.finite_rings + sage: i3.norm() == i1.norm() * i2.norm() # optional - sage.rings.finite_rings True - sage: i1.norm() # optional - sage.libs.pari + sage: i1.norm() # optional - sage.rings.finite_rings x^2 - sage: i1.norm() == x ** L.degree() # optional - sage.libs.pari + sage: i1.norm() == x ** L.degree() # optional - sage.rings.finite_rings True - sage: i2.norm() # optional - sage.libs.pari + sage: i2.norm() # optional - sage.rings.finite_rings (x^2 + 1)/x - sage: i2.norm() == y.norm() # optional - sage.libs.pari + sage: i2.norm() == y.norm() # optional - sage.rings.finite_rings True """ n = 1 @@ -800,18 +800,18 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.rings.finite_rings [True, True] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: [f.is_prime() for f,_ in I.factor()] # optional - sage.rings.finite_rings [True, True] sage: K. = FunctionField(QQ); _. = PolynomialRing(K) @@ -848,21 +848,21 @@ def valuation(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) # optional - sage.libs.pari - sage: I.is_prime() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x, (1/(x^3 + x^2 + x))*y^2) # optional - sage.rings.finite_rings + sage: I.is_prime() # optional - sage.rings.finite_rings True - sage: J = O.ideal(y) # optional - sage.libs.pari - sage: I.valuation(J) # optional - sage.libs.pari + sage: J = O.ideal(y) # optional - sage.rings.finite_rings + sage: I.valuation(J) # optional - sage.rings.finite_rings 2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.rings.finite_rings [-1, 2] The method closely follows Algorithm 4.8.17 of [Coh1993]_. @@ -917,20 +917,20 @@ def prime_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.rings.finite_rings [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, Ideal (x^2 + x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: [f.prime_below() for f,_ in I.factor()] # optional - sage.rings.finite_rings [Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2, Ideal (x + 1) of Maximal order of Rational function field in x over Finite Field of size 2] @@ -950,11 +950,11 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I == I.factor().prod() # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: I == I.factor().prod() # indirect doctest # optional - sage.rings.finite_rings True """ O = self.ring() @@ -993,10 +993,10 @@ class FunctionFieldIdeal_global(FunctionFieldIdeal_polymod): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.ideal(y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.ideal(y) # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + x^3*y + x """ def __init__(self, ring, hnf, denominator=1): @@ -1005,11 +1005,11 @@ def __init__(self, ring, hnf, denominator=1): TESTS:: - sage: K. = FunctionField(GF(5)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3*y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: TestSuite(I).run() # optional - sage.rings.finite_rings """ FunctionFieldIdeal_polymod.__init__(self, ring, hnf, denominator) @@ -1022,18 +1022,18 @@ def __pow__(self, mod): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^7 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: J = O.ideal(x + y) # optional - sage.libs.pari - sage: S = I / J # optional - sage.libs.pari - sage: a = S^100 # optional - sage.libs.pari - sage: _ = S.gens_two() # optional - sage.libs.pari - sage: b = S^100 # faster # optional - sage.libs.pari - sage: b == I^100 / J^100 # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^7 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: J = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: S = I / J # optional - sage.rings.finite_rings + sage: a = S^100 # optional - sage.rings.finite_rings + sage: _ = S.gens_two() # optional - sage.rings.finite_rings + sage: b = S^100 # faster # optional - sage.rings.finite_rings + sage: b == I^100 / J^100 # optional - sage.rings.finite_rings True - sage: b == a # optional - sage.libs.pari + sage: b == a # optional - sage.rings.finite_rings True """ if mod > 2 and self._gens_two_vecs is not None: @@ -1068,17 +1068,17 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x^3*Y - x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^4 + x^2 + x, y + x) - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^3 + 1, y + x) """ if self._gens_two.is_in_cache(): @@ -1094,25 +1094,25 @@ def gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: I # indirect doctest # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: ~I # indirect doctest # optional - sage.libs.pari + sage: ~I # indirect doctest # optional - sage.rings.finite_rings Ideal ((1/(x^6 + x^4 + x^2))*y^2) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y) # optional - sage.libs.pari - sage: I # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y) # optional - sage.rings.finite_rings + sage: I # indirect doctest # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: ~I # indirect doctest # optional - sage.libs.pari + sage: ~I # indirect doctest # optional - sage.rings.finite_rings Ideal ((x/(x^2 + 1))*y + x/(x^2 + 1)) of Maximal order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1147,17 +1147,17 @@ def _gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2, x*y, x + y) # optional - sage.libs.pari - sage: I._gens_two() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2, x*y, x + y) # optional - sage.rings.finite_rings + sage: I._gens_two() # optional - sage.rings.finite_rings (x, y) - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y - x) # optional - sage.libs.pari - sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y - x) # optional - sage.rings.finite_rings + sage: y.zeros()[0].prime_ideal()._gens_two() # optional - sage.rings.finite_rings (x,) """ O = self.ring() @@ -1258,10 +1258,10 @@ class FunctionFieldIdealInfinite_polymod(FunctionFieldIdealInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(1/y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.ideal(1/y) # optional - sage.rings.finite_rings Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 """ @@ -1271,11 +1271,11 @@ def __init__(self, ring, ideal): TESTS:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings + sage: TestSuite(I).run() # optional - sage.rings.finite_rings """ FunctionFieldIdealInfinite.__init__(self, ring) self._ideal = ideal @@ -1286,17 +1286,17 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: d = { I: 1 } # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings + sage: d = { I: 1 } # optional - sage.rings.finite_rings - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: d = { I: 1 } # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings + sage: d = { I: 1 } # optional - sage.rings.finite_rings """ return hash((self.ring(), self._ideal)) @@ -1310,15 +1310,15 @@ def __contains__(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y) # optional - sage.libs.pari - sage: 1/y in I # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/y) # optional - sage.rings.finite_rings + sage: 1/y in I # optional - sage.rings.finite_rings True - sage: 1/x in I # optional - sage.libs.pari + sage: 1/x in I # optional - sage.rings.finite_rings False - sage: 1/x^2 in I # optional - sage.libs.pari + sage: 1/x^2 in I # optional - sage.rings.finite_rings True """ F = self.ring().fraction_field() @@ -1335,21 +1335,21 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I + J # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I + J # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1365,21 +1365,21 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I * J # optional - sage.rings.finite_rings Ideal (1/x^7*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I * J # optional - sage.rings.finite_rings Ideal (1/x^4*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1391,11 +1391,11 @@ def __pow__(self, n): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: J^3 # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: J^3 # optional - sage.rings.finite_rings Ideal (1/x^3) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 """ @@ -1407,25 +1407,25 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(y) # optional - sage.libs.pari - sage: ~J # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(y) # optional - sage.rings.finite_rings + sage: ~J # optional - sage.rings.finite_rings Ideal (1/x^4*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: J * ~J # optional - sage.libs.pari + sage: J * ~J # optional - sage.rings.finite_rings Ideal (1) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: J = Oinf.ideal(y) # optional - sage.libs.pari - sage: ~J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(y) # optional - sage.rings.finite_rings + sage: ~J # optional - sage.rings.finite_rings Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x - sage: J * ~J # optional - sage.libs.pari + sage: J * ~J # optional - sage.rings.finite_rings Ideal (1) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1437,32 +1437,32 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J == J * I # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I * J == J * I # optional - sage.rings.finite_rings True - sage: I + J == J # optional - sage.libs.pari + sage: I + J == J # optional - sage.rings.finite_rings True - sage: I + J == I # optional - sage.libs.pari + sage: I + J == I # optional - sage.rings.finite_rings False - sage: (I < J) == (not J < I) # optional - sage.libs.pari + sage: (I < J) == (not J < I) # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I * J == J * I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x^2*1/y) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I * J == J * I # optional - sage.rings.finite_rings True - sage: I + J == J # optional - sage.libs.pari + sage: I + J == J # optional - sage.rings.finite_rings True - sage: I + J == I # optional - sage.libs.pari + sage: I + J == I # optional - sage.rings.finite_rings False - sage: (I < J) == (not J < I) # optional - sage.libs.pari + sage: (I < J) == (not J < I) # optional - sage.rings.finite_rings True """ return richcmp(self._ideal, other._ideal, op) @@ -1474,11 +1474,11 @@ def _relative_degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: [J._relative_degree for J,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: [J._relative_degree for J,_ in I.factor()] # optional - sage.rings.finite_rings [1] """ if not self.is_prime(): @@ -1492,18 +1492,18 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x, y, 1/x^2*y^2) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x, y) """ F = self.ring().fraction_field() @@ -1516,18 +1516,18 @@ def gens_two(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_two() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens_two() # optional - sage.rings.finite_rings (x, y) - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_two() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens_two() # optional - sage.rings.finite_rings (x,) """ F = self.ring().fraction_field() @@ -1540,11 +1540,11 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + y) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + y) # optional - sage.rings.finite_rings + sage: I.gens_over_base() # optional - sage.rings.finite_rings (x, y, 1/x^2*y^2) """ F = self.ring().fraction_field() @@ -1557,11 +1557,11 @@ def ideal_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/y^2) # optional - sage.libs.pari - sage: I.ideal_below() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/y^2) # optional - sage.rings.finite_rings + sage: I.ideal_below() # optional - sage.rings.finite_rings Ideal (x^3) of Maximal order of Rational function field in x over Finite Field in z2 of size 3^2 """ @@ -1573,30 +1573,30 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: I.is_prime() # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.rings.finite_rings False - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings + sage: J.is_prime() # optional - sage.rings.finite_rings True - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: I.is_prime() # optional - sage.libs.pari + sage: I.is_prime() # optional - sage.rings.finite_rings False - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings + sage: J.is_prime() # optional - sage.rings.finite_rings True """ return self._ideal.is_prime() @@ -1608,31 +1608,31 @@ def prime_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(3^2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 + t^2 - x^4) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (1/x^3*y^2) of Maximal infinite order of Function field in y defined by y^3 + y^2 + 2*x^4)^3 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings + sage: J.is_prime() # optional - sage.rings.finite_rings True - sage: J.prime_below() # optional - sage.libs.pari + sage: J.prime_below() # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field in z2 of size 3^2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: I.factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: I.factor() # optional - sage.rings.finite_rings (Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x)^2 - sage: J = I.factor()[0][0] # optional - sage.libs.pari - sage: J.is_prime() # optional - sage.libs.pari + sage: J = I.factor()[0][0] # optional - sage.rings.finite_rings + sage: J.is_prime() # optional - sage.rings.finite_rings True - sage: J.prime_below() # optional - sage.libs.pari + sage: J.prime_below() # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -1653,11 +1653,11 @@ def valuation(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(y) # optional - sage.libs.pari - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(y) # optional - sage.rings.finite_rings + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.rings.finite_rings [-1] """ if not self.is_prime(): @@ -1671,12 +1671,12 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: f = 1/x # optional - sage.libs.pari - sage: I = Oinf.ideal(f) # optional - sage.libs.pari - sage: I._factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: f = 1/x # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(f) # optional - sage.rings.finite_rings + sage: I._factor() # optional - sage.rings.finite_rings [(Ideal (1/x, 1/x^4*y^2 + 1/x^2*y + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1), (Ideal (1/x, 1/x^2*y + 1) of Maximal infinite order of Function field in y diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 4ec75b2eb45..61cf36777c6 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -198,7 +198,7 @@ def is_prime(self): sage: K. = FunctionField(QQ) sage: O = K.maximal_order() sage: I = O.ideal(x^3 + x^2) - sage: [f.is_prime() for f,m in I.factor()] # optional - sage.libs.pari + sage: [f.is_prime() for f,m in I.factor()] # optional - sage.rings.finite_rings [True, True] """ return self._gen.denominator() == 1 and self._gen.numerator().is_prime() @@ -234,10 +234,10 @@ def gen(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari - sage: I.gen() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 + x) # optional - sage.rings.finite_rings + sage: I.gen() # optional - sage.rings.finite_rings x^2 + x """ return self._gen @@ -248,10 +248,10 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 + x) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (x^2 + x,) """ return (self._gen,) @@ -263,10 +263,10 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 + x) # optional - sage.rings.finite_rings + sage: I.gens_over_base() # optional - sage.rings.finite_rings (x^2 + x,) """ return (self._gen,) @@ -284,7 +284,7 @@ def valuation(self, ideal): sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: I = O.ideal(x^2*(x^2+x+1)^3) - sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.libs.pari + sage: [f.valuation(I) for f,_ in I.factor()] # optional - sage.rings.finite_rings [2, 3] """ if not self.is_prime(): @@ -307,13 +307,13 @@ def _valuation(self, ideal): sage: F. = FunctionField(QQ) sage: O = F.maximal_order() sage: p = O.ideal(x) - sage: p.valuation(O.ideal(x + 1)) # indirect doctest # optional - sage.libs.pari + sage: p.valuation(O.ideal(x + 1)) # indirect doctest # optional - sage.rings.finite_rings 0 - sage: p.valuation(O.ideal(x^2)) # indirect doctest # optional - sage.libs.pari + sage: p.valuation(O.ideal(x^2)) # indirect doctest # optional - sage.rings.finite_rings 2 - sage: p.valuation(O.ideal(1/x^3)) # indirect doctest # optional - sage.libs.pari + sage: p.valuation(O.ideal(1/x^3)) # indirect doctest # optional - sage.rings.finite_rings -3 - sage: p.valuation(O.ideal(0)) # indirect doctest # optional - sage.libs.pari + sage: p.valuation(O.ideal(0)) # indirect doctest # optional - sage.rings.finite_rings +Infinity """ return ideal.gen().valuation(self.gen()) @@ -325,10 +325,10 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^3*(x+1)^2) # optional - sage.libs.pari - sage: I.factor() # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^3*(x+1)^2) # optional - sage.rings.finite_rings + sage: I.factor() # indirect doctest # optional - sage.rings.finite_rings (Ideal (x) of Maximal order of Rational function field in x over Finite Field in z2 of size 2^2)^3 * (Ideal (x + 1) of Maximal order of Rational function field in x @@ -351,9 +351,9 @@ class FunctionFieldIdealInfinite_rational(FunctionFieldIdealInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ideal(x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.ideal(x) # optional - sage.rings.finite_rings Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ def __init__(self, ring, gen): @@ -362,10 +362,10 @@ def __init__(self, ring, gen): TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x) # optional - sage.libs.pari - sage: TestSuite(I).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x) # optional - sage.rings.finite_rings + sage: TestSuite(I).run() # optional - sage.rings.finite_rings """ FunctionFieldIdealInfinite.__init__(self, ring) self._gen = gen @@ -376,11 +376,11 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/x) # optional - sage.libs.pari - sage: d = { I: 1, J: 2 } # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/x) # optional - sage.rings.finite_rings + sage: d = { I: 1, J: 2 } # optional - sage.rings.finite_rings """ return hash( (self.ring(), self._gen) ) @@ -414,11 +414,11 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x + 1) # optional - sage.libs.pari - sage: J = Oinf.ideal(x^2 + x) # optional - sage.libs.pari - sage: I + J == J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x + 1) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(x^2 + x) # optional - sage.rings.finite_rings + sage: I + J == J # optional - sage.rings.finite_rings True """ return richcmp(self._gen, other._gen, op) @@ -433,11 +433,11 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari - sage: I + J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.rings.finite_rings + sage: I + J # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -453,11 +453,11 @@ def _mul_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: J = Oinf.ideal(1/(x+1)) # optional - sage.libs.pari - sage: I * J # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.rings.finite_rings + sage: J = Oinf.ideal(1/(x+1)) # optional - sage.rings.finite_rings + sage: I * J # optional - sage.rings.finite_rings Ideal (1/x^2) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -473,10 +473,10 @@ def _acted_upon_(self, other, on_left): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.libs.pari - sage: x * I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2+1)) # optional - sage.rings.finite_rings + sage: x * I # optional - sage.rings.finite_rings Ideal (1) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -488,10 +488,10 @@ def __invert__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari - sage: ~I # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.rings.finite_rings + sage: ~I # indirect doctest # optional - sage.rings.finite_rings Ideal (x) of Maximal infinite order of Rational function field in x over Finite Field of size 2 """ @@ -503,10 +503,10 @@ def is_prime(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.libs.pari - sage: I.is_prime() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x/(x^2 + 1)) # optional - sage.rings.finite_rings + sage: I.is_prime() # optional - sage.rings.finite_rings True """ x = self._ring.fraction_field().gen() @@ -518,10 +518,10 @@ def gen(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gen() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.rings.finite_rings + sage: I.gen() # optional - sage.rings.finite_rings 1/x^2 """ return self._gen @@ -532,10 +532,10 @@ def gens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings (1/x^2,) """ return (self._gen,) @@ -547,10 +547,10 @@ def gens_over_base(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.libs.pari - sage: I.gens_over_base() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x+1)/(x^3+x), (x^2+1)/x^4) # optional - sage.rings.finite_rings + sage: I.gens_over_base() # optional - sage.rings.finite_rings (1/x^2,) """ return (self._gen,) @@ -588,10 +588,10 @@ def _factor(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: Oinf = K.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal((x+1)/(x^3+1)) # optional - sage.libs.pari - sage: I._factor() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: Oinf = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal((x+1)/(x^3+1)) # optional - sage.rings.finite_rings + sage: I._factor() # optional - sage.rings.finite_rings [(Ideal (1/x) of Maximal infinite order of Rational function field in x over Finite Field of size 2, 2)] """ diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 4cfd95414ff..0a4e178dff1 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -396,10 +396,10 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field - sage: f._repr_type() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f._repr_type() # optional - sage.rings.finite_rings sage.rings.function_field 'Function Field' """ return "Function Field" @@ -410,10 +410,10 @@ def _repr_defn(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field - sage: f._repr_defn() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f._repr_defn() # optional - sage.rings.finite_rings sage.rings.function_field 'y |--> 2*y' """ a = '%s |--> %s' % (self.domain().variable_name(), self._im_gen) @@ -428,14 +428,14 @@ class FunctionFieldMorphism_polymod(FunctionFieldMorphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field - sage: f = L.hom(y*2); f # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = L.hom(y*2); f # optional - sage.rings.finite_rings sage.rings.function_field Function Field endomorphism of Function field in y defined by y^3 + 6*x^3 + x Defn: y |--> 2*y - sage: factor(L.polynomial()) # optional - sage.libs.pari sage.rings.function_field + sage: factor(L.polynomial()) # optional - sage.rings.finite_rings sage.rings.function_field y^3 + 6*x^3 + x - sage: f(y).charpoly('y') # optional - sage.libs.pari sage.rings.function_field + sage: f(y).charpoly('y') # optional - sage.rings.finite_rings sage.rings.function_field y^3 + 6*x^3 + x """ def __init__(self, parent, im_gen, base_morphism): @@ -444,10 +444,10 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.libs.pari sage.rings.function_field - sage: f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(f).run(skip="_test_category") # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = L.hom(y*2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(f).run(skip="_test_category") # optional - sage.rings.finite_rings sage.rings.function_field """ FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism) # Verify that the morphism is valid: @@ -463,11 +463,11 @@ def _call_(self, x): """ EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.libs.pari sage.rings.function_field - sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: f(y/x + x^2/(x+1)) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field 2/x*y + x^2/(x + 1) - sage: f(y) # optional - sage.libs.pari sage.rings.function_field + sage: f(y) # optional - sage.rings.finite_rings sage.rings.function_field 2*y """ v = x.list() @@ -487,8 +487,8 @@ def __init__(self, parent, im_gen, base_morphism): EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: f = K.hom(1/x); f # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: f = K.hom(1/x); f # optional - sage.rings.finite_rings Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> 1/x """ @@ -498,13 +498,13 @@ def _call_(self, x): """ EXAMPLES:: - sage: K. = FunctionField(GF(7)) # optional - sage.libs.pari - sage: f = K.hom(1/x); f # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)) # optional - sage.rings.finite_rings + sage: f = K.hom(1/x); f # optional - sage.rings.finite_rings Function Field endomorphism of Rational function field in x over Finite Field of size 7 Defn: x |--> 1/x - sage: f(x+1) # indirect doctest # optional - sage.libs.pari + sage: f(x+1) # indirect doctest # optional - sage.rings.finite_rings (x + 1)/x - sage: 1/x + 1 # optional - sage.libs.pari + sage: 1/x + 1 # optional - sage.rings.finite_rings (x + 1)/x You can specify a morphism on the base ring:: @@ -722,35 +722,35 @@ class FunctionFieldCompletion(Map): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m # optional - sage.rings.finite_rings sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 - sage: m(x) # optional - sage.libs.pari sage.rings.function_field + sage: m(x) # optional - sage.rings.finite_rings sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) - sage: m(y) # optional - sage.libs.pari sage.rings.function_field + sage: m(y) # optional - sage.rings.finite_rings sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) - sage: m(x*y) == m(x) * m(y) # optional - sage.libs.pari sage.rings.function_field + sage: m(x*y) == m(x) * m(y) # optional - sage.rings.finite_rings sage.rings.function_field True - sage: m(x+y) == m(x) + m(y) # optional - sage.libs.pari sage.rings.function_field + sage: m(x+y) == m(x) + m(y) # optional - sage.rings.finite_rings sage.rings.function_field True The variable name of the series can be supplied. If the place is not rational such that the residue field is a proper extension of the constant field, you can also specify the generator name of the extension:: - sage: p2 = L.places_finite(2)[0] # optional - sage.libs.pari sage.rings.function_field - sage: p2 # optional - sage.libs.pari sage.rings.function_field + sage: p2 = L.places_finite(2)[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p2 # optional - sage.rings.finite_rings sage.rings.function_field Place (x^2 + x + 1, x*y + 1) - sage: m2 = L.completion(p2, 't', gen_name='b') # optional - sage.libs.pari sage.rings.function_field - sage: m2(x) # optional - sage.libs.pari sage.rings.function_field + sage: m2 = L.completion(p2, 't', gen_name='b') # optional - sage.rings.finite_rings sage.rings.function_field + sage: m2(x) # optional - sage.rings.finite_rings sage.rings.function_field (b + 1) + t + t^2 + t^4 + t^8 + t^16 + O(t^20) - sage: m2(y) # optional - sage.libs.pari sage.rings.function_field + sage: m2(y) # optional - sage.rings.finite_rings sage.rings.function_field b + b*t + b*t^3 + b*t^4 + (b + 1)*t^5 + (b + 1)*t^7 + b*t^9 + b*t^11 + b*t^12 + b*t^13 + b*t^15 + b*t^16 + (b + 1)*t^17 + (b + 1)*t^19 + O(t^20) """ @@ -760,11 +760,11 @@ def __init__(self, field, place, name=None, prec=None, gen_name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m # optional - sage.rings.finite_rings sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -798,11 +798,11 @@ def _repr_type(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field Completion map: From: Function field in y defined by y^2 + y + (x^2 + 1)/x To: Laurent Series Ring in s over Finite Field of size 2 @@ -815,11 +815,11 @@ def _call_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m(y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m(y) # optional - sage.rings.finite_rings sage.rings.function_field s^-1 + 1 + s^3 + s^5 + s^7 + s^9 + s^13 + s^15 + s^17 + O(s^19) """ if self._precision == infinity: @@ -833,11 +833,11 @@ def _call_with_args(self, f, args, kwds): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m(x+y, 10) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m(x+y, 10) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field s^-1 + 1 + s^2 + s^4 + s^8 + O(s^9) """ if self._precision == infinity: @@ -857,11 +857,11 @@ def _expand(self, f, prec=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m(x, prec=20) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m(x, prec=20) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + s^9 + s^10 + s^12 + s^13 + s^15 + s^16 + s^17 + s^19 + O(s^22) """ @@ -891,15 +891,15 @@ def _expand_lazy(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p, prec=infinity) # optional - sage.libs.pari sage.rings.function_field - sage: e = m(x); e # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p, prec=infinity) # optional - sage.rings.finite_rings sage.rings.function_field + sage: e = m(x); e # optional - sage.rings.finite_rings sage.rings.function_field s^2 + s^3 + s^4 + s^5 + s^7 + s^8 + ... - sage: e.coefficient(99) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: e.coefficient(99) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field 0 - sage: e.coefficient(100) # optional - sage.libs.pari sage.rings.function_field + sage: e.coefficient(100) # optional - sage.rings.finite_rings sage.rings.function_field 1 """ place = self._place @@ -923,11 +923,11 @@ def default_precision(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: m = L.completion(p) # optional - sage.libs.pari sage.rings.function_field - sage: m.default_precision() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: m = L.completion(p) # optional - sage.rings.finite_rings sage.rings.function_field + sage: m.default_precision() # optional - sage.rings.finite_rings sage.rings.function_field 20 """ return self._precision @@ -943,14 +943,14 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: R = p.valuation_ring() # optional - sage.libs.pari sage.rings.function_field - sage: k, fr_k, to_k = R.residue_field() # optional - sage.libs.pari sage.rings.function_field - sage: k # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: R = p.valuation_ring() # optional - sage.rings.finite_rings sage.rings.function_field + sage: k, fr_k, to_k = R.residue_field() # optional - sage.rings.finite_rings sage.rings.function_field + sage: k # optional - sage.rings.finite_rings sage.rings.function_field Finite Field of size 2 - sage: fr_k # optional - sage.libs.pari sage.rings.function_field + sage: fr_k # optional - sage.rings.finite_rings sage.rings.function_field Ring morphism: From: Finite Field of size 2 To: Valuation ring at Place (x, x*y) @@ -971,13 +971,13 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^2-x^3-1) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(x - 2) # optional - sage.libs.pari sage.rings.function_field - sage: D = I.divisor() # optional - sage.libs.pari sage.rings.function_field - sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari sage.rings.function_field - sage: from_V # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^2-x^3-1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(x - 2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: D = I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field + sage: V, from_V, to_V = D.function_space() # optional - sage.rings.finite_rings sage.rings.function_field + sage: from_V # optional - sage.rings.finite_rings sage.rings.function_field Linear map: From: Vector space of dimension 2 over Finite Field of size 5 To: Function field in y defined by y^2 + 4*x^3 + 4 @@ -998,13 +998,13 @@ def _repr_(self) -> str: EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(x - 2) # optional - sage.libs.pari sage.rings.function_field - sage: D = I.divisor() # optional - sage.libs.pari sage.rings.function_field - sage: V, from_V, to_V = D.function_space() # optional - sage.libs.pari sage.rings.function_field - sage: to_V # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(x - 2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: D = I.divisor() # optional - sage.rings.finite_rings sage.rings.function_field + sage: V, from_V, to_V = D.function_space() # optional - sage.rings.finite_rings sage.rings.function_field + sage: to_V # optional - sage.rings.finite_rings sage.rings.function_field Section of linear map: From: Function field in y defined by y^2 + 4*x^3 + 4 To: Vector space of dimension 2 over Finite Field of size 5 diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index b8358e2e002..d44c6513829 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -30,39 +30,39 @@ `O` and one maximal infinite order `O_\infty`. There are other non-maximal orders such as equation orders:: - sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^3 - y - x) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: 1/y in O # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(3)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^3 - y - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: 1/y in O # optional - sage.rings.finite_rings sage.rings.function_field False - sage: x/y in O # optional - sage.libs.pari sage.rings.function_field + sage: x/y in O # optional - sage.rings.finite_rings sage.rings.function_field True Sage provides an extensive functionality for computations in maximal orders of function fields. For example, you can decompose a prime ideal of a rational function field in an extension:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: p = o.ideal(x + 1) # optional - sage.libs.pari - sage: p.is_prime() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: o = K.maximal_order() # optional - sage.rings.finite_rings + sage: p = o.ideal(x + 1) # optional - sage.rings.finite_rings + sage: p.is_prime() # optional - sage.rings.finite_rings True - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.decomposition(p) # optional - sage.libs.pari sage.rings.function_field + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.decomposition(p) # optional - sage.rings.finite_rings sage.rings.function_field [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 2, 1)] - sage: p1, relative_degree,ramification_index = O.decomposition(p)[1] # optional - sage.libs.pari sage.rings.function_field - sage: p1.parent() # optional - sage.libs.pari sage.rings.function_field + sage: p1, relative_degree,ramification_index = O.decomposition(p)[1] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1.parent() # optional - sage.rings.finite_rings sage.rings.function_field Monoid of ideals of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: relative_degree # optional - sage.libs.pari sage.rings.function_field + sage: relative_degree # optional - sage.rings.finite_rings sage.rings.function_field 2 - sage: ramification_index # optional - sage.libs.pari sage.rings.function_field + sage: ramification_index # optional - sage.rings.finite_rings sage.rings.function_field 1 When the base constant field is the algebraic field `\QQbar`, the only prime ideals @@ -279,9 +279,9 @@ def _repr_(self): sage: FunctionField(QQ,'y').maximal_order_infinite() Maximal infinite order of Rational function field in y over Rational Field - sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari sage.rings.function_field - sage: F.maximal_order_infinite() # optional - sage.libs.pari sage.modules sage.rings.function_field + sage: K. = FunctionField(GF(2)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings sage.rings.function_field + sage: F.maximal_order_infinite() # optional - sage.rings.finite_rings sage.modules sage.rings.function_field Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ return "Maximal infinite order of %s"%(self.function_field(),) diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index 3d2f2a1054e..f3428cf9e3b 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -1,5 +1,5 @@ # sage.doctest: optional - sage.modules (because __init__ constructs a vector space) -# some tests are marked # optional - sage.libs.pari (because they use finite fields) +# some tests are marked # optional - sage.rings.finite_rings (because they use finite fields) r""" Orders of function fields given by a basis over the maximal order of the base field """ @@ -30,9 +30,9 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.rings.finite_rings sage.rings.function_field Order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under @@ -67,10 +67,10 @@ def __init__(self, basis, check=True): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(O).run() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(O).run() # optional - sage.rings.finite_rings sage.rings.function_field """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -152,13 +152,13 @@ def ideal_with_gens_over_base(self, gens): We construct some ideals in a nontrivial function field:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.rings.finite_rings sage.rings.function_field Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari sage.rings.function_field + sage: I.module() # optional - sage.rings.finite_rings sage.rings.function_field Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -167,14 +167,14 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.rings.function_field + sage: y in I # optional - sage.rings.finite_rings sage.rings.function_field True - sage: y^2 in I # optional - sage.libs.pari sage.rings.function_field + sage: y^2 in I # optional - sage.rings.finite_rings sage.rings.function_field False """ F = self.function_field() @@ -207,16 +207,16 @@ def ideal(self, *gens): A fractional ideal of a nontrivial extension:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: S = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: S.ideal(1/y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 - 4) # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: S = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: S.ideal(1/y) # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari sage.rings.function_field + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.rings.finite_rings sage.rings.function_field Ideal (x^2 + 3) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari sage.rings.function_field + sage: I2 == S.ideal(I) # optional - sage.rings.finite_rings sage.rings.function_field True """ if len(gens) == 1: @@ -236,10 +236,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.polynomial() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.polynomial() # optional - sage.rings.finite_rings sage.rings.function_field y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -250,10 +250,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.basis() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.basis() # optional - sage.rings.finite_rings sage.rings.function_field (1, y, y^2, y^3) """ return self._basis @@ -265,10 +265,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.free_module() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.free_module() # optional - sage.rings.finite_rings sage.rings.function_field Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -289,11 +289,11 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: f = (x + y)^3 # optional - sage.libs.pari sage.rings.function_field - sage: O.coordinate_vector(f) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: f = (x + y)^3 # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.coordinate_vector(f) # optional - sage.rings.finite_rings sage.rings.function_field (x^3, 3*x^2, 3*x, 1) """ return self._module.coordinate_vector(self._to_module(e), check=False) @@ -312,16 +312,16 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order_infinite(); O # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order_infinite(); O # optional - sage.rings.finite_rings sage.rings.function_field Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 The basis only defines an order if the module it generates is closed under multiplication and contains the identity element (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.libs.pari sage.rings.function_field + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, y^3]); O # optional - sage.rings.finite_rings sage.rings.function_field Traceback (most recent call last): ... ValueError: the module generated by basis (1, y, 1/x^2*y^2, y^3) must be closed under multiplication @@ -330,7 +330,7 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): degree of the function field of its elements (only checked when ``check`` is ``True``):: - sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.libs.pari sage.rings.function_field + sage: O = L.order_infinite_with_basis([1, y, 1/x^2*y^2, 1 + y]); O # optional - sage.rings.finite_rings sage.rings.function_field Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -338,9 +338,9 @@ class FunctionFieldOrderInfinite_basis(FunctionFieldOrderInfinite): Note that 1 does not need to be an element of the basis, as long as it is in the module spanned by it:: - sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.libs.pari sage.rings.function_field + sage: O = L.order_infinite_with_basis([1 + 1/x*y, 1/x*y, 1/x^2*y^2, 1/x^3*y^3]); O # optional - sage.rings.finite_rings sage.rings.function_field Infinite order in Function field in y defined by y^4 + x*y + 4*x + 1 - sage: O.basis() # optional - sage.libs.pari sage.rings.function_field + sage: O.basis() # optional - sage.rings.finite_rings sage.rings.function_field (1/x*y + 1, 1/x*y, 1/x^2*y^2, 1/x^3*y^3) """ def __init__(self, basis, check=True): @@ -349,10 +349,10 @@ def __init__(self, basis, check=True): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order_infinite() # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(O).run() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order_infinite() # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(O).run() # optional - sage.rings.finite_rings sage.rings.function_field """ if len(basis) == 0: raise ValueError("basis must have positive length") @@ -442,13 +442,13 @@ def ideal_with_gens_over_base(self, gens): We construct some ideals in a nontrivial function field:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order(); O # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order(); O # optional - sage.rings.finite_rings sage.rings.function_field Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari sage.rings.function_field + sage: I.module() # optional - sage.rings.finite_rings sage.rings.function_field Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: [1 0] @@ -456,14 +456,14 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.rings.finite_rings sage.rings.function_field Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari sage.rings.function_field + sage: y in I # optional - sage.rings.finite_rings sage.rings.function_field True - sage: y^2 in I # optional - sage.libs.pari sage.rings.function_field + sage: y^2 in I # optional - sage.rings.finite_rings sage.rings.function_field False """ F = self.function_field() @@ -519,10 +519,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.polynomial() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.polynomial() # optional - sage.rings.finite_rings sage.rings.function_field y^4 + x*y + 4*x + 1 """ return self._field.polynomial() @@ -533,10 +533,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.basis() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.basis() # optional - sage.rings.finite_rings sage.rings.function_field (1, y, y^2, y^3) """ return self._basis @@ -548,10 +548,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = L.equation_order() # optional - sage.libs.pari sage.rings.function_field - sage: O.free_module() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.equation_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O.free_module() # optional - sage.rings.finite_rings sage.rings.function_field Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 2b162c01d19..0026786fa09 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -37,10 +37,10 @@ def __init__(self, field, ideal_class=FunctionFieldIdeal_polymod): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: TestSuite(O).run() # optional - sage.rings.finite_rings """ FunctionFieldMaximalOrder.__init__(self, field, ideal_class) @@ -132,26 +132,26 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: y in O # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 - x*Y + x^2 + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: y in O # optional - sage.rings.finite_rings True - sage: 1/y in O # optional - sage.libs.pari + sage: 1/y in O # optional - sage.rings.finite_rings False - sage: x in O # optional - sage.libs.pari + sage: x in O # optional - sage.rings.finite_rings True - sage: 1/x in O # optional - sage.libs.pari + sage: 1/x in O # optional - sage.rings.finite_rings False - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: 1 in O # optional - sage.libs.pari + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: 1 in O # optional - sage.rings.finite_rings True - sage: y in O # optional - sage.libs.pari + sage: y in O # optional - sage.rings.finite_rings False - sage: x*y in O # optional - sage.libs.pari + sage: x*y in O # optional - sage.rings.finite_rings True - sage: x^2*y in O # optional - sage.libs.pari + sage: x^2*y in O # optional - sage.rings.finite_rings True """ F = self.function_field() @@ -174,13 +174,13 @@ def ideal_with_gens_over_base(self, gens): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order(); O # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order(); O # optional - sage.rings.finite_rings Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.libs.pari + sage: I = O.ideal_with_gens_over_base([1, y]); I # optional - sage.rings.finite_rings Ideal (1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I.module() # optional - sage.libs.pari + sage: I.module() # optional - sage.rings.finite_rings Free module of degree 2 and rank 2 over Maximal order of Rational function field in x over Finite Field of size 7 Echelon basis matrix: @@ -189,14 +189,14 @@ def ideal_with_gens_over_base(self, gens): There is no check if the resulting object is really an ideal:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.equation_order() # optional - sage.rings.finite_rings + sage: I = O.ideal_with_gens_over_base([y]); I # optional - sage.rings.finite_rings Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6 - sage: y in I # optional - sage.libs.pari + sage: y in I # optional - sage.rings.finite_rings True - sage: y^2 in I # optional - sage.libs.pari + sage: y^2 in I # optional - sage.rings.finite_rings False """ return self._ideal_from_vectors([self.coordinate_vector(g) for g in gens]) @@ -212,16 +212,16 @@ def _ideal_from_vectors(self, vecs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: v1 = O.coordinate_vector(x^3 + 1) # optional - sage.libs.pari - sage: v2 = O.coordinate_vector(y) # optional - sage.libs.pari - sage: v1 # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: v1 = O.coordinate_vector(x^3 + 1) # optional - sage.rings.finite_rings + sage: v2 = O.coordinate_vector(y) # optional - sage.rings.finite_rings + sage: v1 # optional - sage.rings.finite_rings (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari + sage: v2 # optional - sage.rings.finite_rings (0, 1) - sage: O._ideal_from_vectors([v1, v2]) # optional - sage.libs.pari + sage: O._ideal_from_vectors([v1, v2]) # optional - sage.rings.finite_rings Ideal (y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -245,18 +245,18 @@ def _ideal_from_vectors_and_denominator(self, vecs, d=1, check=True): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(y^2) # optional - sage.libs.pari - sage: m = I.basis_matrix() # optional - sage.libs.pari - sage: v1 = m[0] # optional - sage.libs.pari - sage: v2 = m[1] # optional - sage.libs.pari - sage: v1 # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(y^2) # optional - sage.rings.finite_rings + sage: m = I.basis_matrix() # optional - sage.rings.finite_rings + sage: v1 = m[0] # optional - sage.rings.finite_rings + sage: v2 = m[1] # optional - sage.rings.finite_rings + sage: v1 # optional - sage.rings.finite_rings (x^3 + 1, 0) - sage: v2 # optional - sage.libs.pari + sage: v2 # optional - sage.rings.finite_rings (0, x^3 + 1) - sage: O._ideal_from_vectors([v1, v2]) # indirect doctest # optional - sage.libs.pari + sage: O._ideal_from_vectors([v1, v2]) # indirect doctest # optional - sage.rings.finite_rings Ideal (x^3 + 1) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 """ @@ -309,17 +309,17 @@ def ideal(self, *gens, **kwargs): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 - 4) # optional - sage.libs.pari - sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.libs.pari - sage: S = L.maximal_order() # optional - sage.libs.pari - sage: S.ideal(1/y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 - 4) # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: S = L.maximal_order() # optional - sage.rings.finite_rings + sage: S.ideal(1/y) # optional - sage.rings.finite_rings Ideal ((1/(x^3 + 1))*y) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.libs.pari + sage: I2 = S.ideal(x^2 - 4); I2 # optional - sage.rings.finite_rings Ideal (x^2 + 3) of Maximal order of Function field in y defined by y^2 + 6*x^3 + 6 - sage: I2 == S.ideal(I) # optional - sage.libs.pari + sage: I2 == S.ideal(I) # optional - sage.rings.finite_rings True sage: K. = FunctionField(QQ); R. = K[] @@ -352,10 +352,10 @@ def polynomial(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.polynomial() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.equation_order() # optional - sage.rings.finite_rings + sage: O.polynomial() # optional - sage.rings.finite_rings y^4 + x*y + 4*x + 1 sage: K. = FunctionField(QQ); R. = K[] @@ -373,10 +373,10 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.equation_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.equation_order() # optional - sage.rings.finite_rings + sage: O.basis() # optional - sage.rings.finite_rings (1, y, y^2, y^3) sage: K. = FunctionField(QQ) @@ -396,16 +396,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.gen() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.gen() # optional - sage.rings.finite_rings 1 - sage: O.gen(1) # optional - sage.libs.pari + sage: O.gen(1) # optional - sage.rings.finite_rings y - sage: O.gen(2) # optional - sage.libs.pari + sage: O.gen(2) # optional - sage.rings.finite_rings (1/(x^3 + x^2 + x))*y^2 - sage: O.gen(3) # optional - sage.libs.pari + sage: O.gen(3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -421,10 +421,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order() # optional - sage.libs.pari - sage: Oinf.ngens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order() # optional - sage.rings.finite_rings + sage: Oinf.ngens() # optional - sage.rings.finite_rings 3 """ return len(self._basis) @@ -435,10 +435,10 @@ def free_module(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.free_module() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.free_module() # optional - sage.rings.finite_rings Free module of degree 4 and rank 4 over Maximal order of Rational function field in x over Finite Field of size 7 User basis matrix: @@ -455,12 +455,12 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.coordinate_vector(y) # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.coordinate_vector(y) # optional - sage.rings.finite_rings (0, 1, 0, 0) - sage: O.coordinate_vector(x*y) # optional - sage.libs.pari + sage: O.coordinate_vector(x*y) # optional - sage.rings.finite_rings (0, x, 0, 0) sage: K. = FunctionField(QQ); R. = K[] @@ -503,10 +503,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.different() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.different() # optional - sage.rings.finite_rings Ideal (y^3 + 2*x) of Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -519,10 +519,10 @@ def codifferent(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O.codifferent() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O.codifferent() # optional - sage.rings.finite_rings Ideal (1, (1/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^3 + ((5*x^3 + 6*x^2 + x + 6)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y^2 + ((x^3 + 2*x^2 + 2*x + 2)/(x^4 + 4*x^3 + 3*x^2 + 6*x + 4))*y @@ -539,10 +539,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: O._codifferent_matrix() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: O._codifferent_matrix() # optional - sage.rings.finite_rings [ 4 0 0 4*x] [ 0 0 4*x 5*x + 3] [ 0 4*x 5*x + 3 0] @@ -570,12 +570,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = o.ideal(x + 1) # optional - sage.libs.pari - sage: O.decomposition(p) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: o = K.maximal_order() # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: p = o.ideal(x + 1) # optional - sage.rings.finite_rings + sage: O.decomposition(p) # optional - sage.rings.finite_rings [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order @@ -698,14 +698,14 @@ class FunctionFieldMaximalOrderInfinite_polymod(FunctionFieldMaximalOrderInfinit EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: F.maximal_order_infinite() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: F.maximal_order_infinite() # optional - sage.rings.finite_rings Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: L.maximal_order_infinite() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: L.maximal_order_infinite() # optional - sage.rings.finite_rings Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ def __init__(self, field, category=None): @@ -714,10 +714,10 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.libs.pari - sage: O = F.maximal_order_infinite() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2+x+1)^2) # optional - sage.rings.finite_rings + sage: O = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: TestSuite(O).run() # optional - sage.rings.finite_rings """ FunctionFieldMaximalOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_polymod) @@ -738,18 +738,18 @@ def _element_constructor_(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.basis() # optional - sage.rings.finite_rings (1, 1/x*y) - sage: 1 in Oinf # optional - sage.libs.pari + sage: 1 in Oinf # optional - sage.rings.finite_rings True - sage: 1/x*y in Oinf # optional - sage.libs.pari + sage: 1/x*y in Oinf # optional - sage.rings.finite_rings True - sage: x*y in Oinf # optional - sage.libs.pari + sage: x*y in Oinf # optional - sage.rings.finite_rings False - sage: 1/x in Oinf # optional - sage.libs.pari + sage: 1/x in Oinf # optional - sage.rings.finite_rings True """ F = self.function_field() @@ -773,18 +773,18 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.basis() # optional - sage.rings.finite_rings (1, 1/x^2*y, (1/(x^4 + x^3 + x^2))*y^2) :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.basis() # optional - sage.rings.finite_rings (1, 1/x*y) """ return self._basis @@ -797,16 +797,16 @@ def gen(self, n=0): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.gen() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.gen() # optional - sage.rings.finite_rings 1 - sage: Oinf.gen(1) # optional - sage.libs.pari + sage: Oinf.gen(1) # optional - sage.rings.finite_rings 1/x^2*y - sage: Oinf.gen(2) # optional - sage.libs.pari + sage: Oinf.gen(2) # optional - sage.rings.finite_rings (1/(x^4 + x^3 + x^2))*y^2 - sage: Oinf.gen(3) # optional - sage.libs.pari + sage: Oinf.gen(3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: there are only 3 generators @@ -822,10 +822,10 @@ def ngens(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.ngens() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.ngens() # optional - sage.rings.finite_rings 3 """ return len(self._basis) @@ -840,19 +840,19 @@ def ideal(self, *gens): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x, y); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x, y); I # optional - sage.rings.finite_rings Ideal (y) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2 :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(x, y); I # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(x, y); I # optional - sage.rings.finite_rings Ideal (x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -941,11 +941,11 @@ def _to_iF(self, I): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: I = Oinf.ideal(y) # optional - sage.libs.pari - sage: Oinf._to_iF(I) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: I = Oinf.ideal(y) # optional - sage.rings.finite_rings + sage: Oinf._to_iF(I) # optional - sage.rings.finite_rings Ideal (1, 1/x*s) of Maximal order of Function field in s defined by s^2 + x*s + x^3 + x """ @@ -962,10 +962,10 @@ def decomposition(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: Oinf = F.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.decomposition() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: Oinf = F.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.decomposition() # optional - sage.rings.finite_rings [(Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1) of Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal ((1/(x^4 + x^3 + x^2))*y^2 + 1/x^2*y + 1) of Maximal infinite order @@ -973,10 +973,10 @@ def decomposition(self): :: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.decomposition() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.decomposition() # optional - sage.rings.finite_rings [(Ideal (1/x*y) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x, 1, 2)] @@ -1020,10 +1020,10 @@ def different(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf.different() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf.different() # optional - sage.rings.finite_rings Ideal (1/x) of Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ @@ -1041,10 +1041,10 @@ def _codifferent_matrix(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: Oinf._codifferent_matrix() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: Oinf._codifferent_matrix() # optional - sage.rings.finite_rings [ 0 1/x] [ 1/x 1/x^2] """ @@ -1072,13 +1072,13 @@ def coordinate_vector(self, e): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: Oinf = L.maximal_order_infinite() # optional - sage.libs.pari - sage: f = 1/y^2 # optional - sage.libs.pari - sage: f in Oinf # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: Oinf = L.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: f = 1/y^2 # optional - sage.rings.finite_rings + sage: f in Oinf # optional - sage.rings.finite_rings True - sage: Oinf.coordinate_vector(f) # optional - sage.libs.pari + sage: Oinf.coordinate_vector(f) # optional - sage.rings.finite_rings ((x^3 + x^2 + x)/(x^4 + 1), x^3/(x^4 + 1)) """ return self._module.coordinate_vector(self._to_module(e)) @@ -1094,9 +1094,9 @@ class FunctionFieldMaximalOrder_global(FunctionFieldMaximalOrder_polymod): EXAMPLES:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: L.maximal_order() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: L.maximal_order() # optional - sage.rings.finite_rings Maximal order of Function field in y defined by y^4 + x*y + 4*x + 1 """ @@ -1106,10 +1106,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: TestSuite(O).run() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^4 + x*y + 4*x + 1) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: TestSuite(O).run() # optional - sage.rings.finite_rings """ FunctionFieldMaximalOrder_polymod.__init__(self, field, ideal_class=FunctionFieldIdeal_global) @@ -1127,12 +1127,12 @@ def p_radical(self, prime): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = o.ideal(x + 1) # optional - sage.libs.pari - sage: O.p_radical(p) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2 * (x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: o = K.maximal_order() # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: p = o.ideal(x + 1) # optional - sage.rings.finite_rings + sage: O.p_radical(p) # optional - sage.rings.finite_rings Ideal (x + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2 """ @@ -1189,12 +1189,12 @@ def decomposition(self, ideal): EXAMPLES:: - sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.libs.pari - sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.libs.pari - sage: o = K.maximal_order() # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = o.ideal(x + 1) # optional - sage.libs.pari - sage: O.decomposition(p) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); R. = K[] # optional - sage.rings.finite_rings + sage: F. = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # optional - sage.rings.finite_rings + sage: o = K.maximal_order() # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: p = o.ideal(x + 1) # optional - sage.rings.finite_rings + sage: O.decomposition(p) # optional - sage.rings.finite_rings [(Ideal (x + 1, y + 1) of Maximal order of Function field in y defined by y^3 + x^6 + x^4 + x^2, 1, 1), (Ideal (x + 1, (1/(x^3 + x^2 + x))*y^2 + y + 1) of Maximal order diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index add36705671..0962cca86ed 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -34,9 +34,9 @@ class FunctionFieldMaximalOrder_rational(FunctionFieldMaximalOrder): EXAMPLES:: - sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)); K # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order(); R # optional - sage.libs.pari + sage: R = K.maximal_order(); R # optional - sage.rings.finite_rings Maximal order of Rational function field in t over Finite Field of size 19 """ def __init__(self, field): @@ -125,44 +125,44 @@ def _residue_field(self, ideal, name=None): EXAMPLES:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Finite Field in z2 of size 2^2 - sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.rings.finite_rings [True, True, True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.rings.finite_rings [True, True, True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.rings.finite_rings + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.rings.finite_rings True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.rings.finite_rings True - sage: to_R(e1).parent() is R # optional - sage.libs.pari + sage: to_R(e1).parent() is R # optional - sage.rings.finite_rings True - sage: to_R(e2).parent() is R # optional - sage.libs.pari + sage: to_R(e2).parent() is R # optional - sage.rings.finite_rings True - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: I = O.ideal(x + 1) # optional - sage.libs.pari - sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: I = O.ideal(x + 1) # optional - sage.rings.finite_rings + sage: R, fr_R, to_R = O._residue_field(I) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Finite Field of size 2 - sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.libs.pari + sage: [to_R(fr_R(e)) == e for e in R] # optional - sage.rings.finite_rings [True, True] - sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.libs.pari + sage: [to_R(fr_R(e)).parent() is R for e in R] # optional - sage.rings.finite_rings [True, True] - sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.libs.pari - sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.libs.pari + sage: e1, e2 = fr_R(R.random_element()), fr_R(R.random_element()) # optional - sage.rings.finite_rings + sage: to_R(e1 * e2) == to_R(e1) * to_R(e2) # optional - sage.rings.finite_rings True - sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.libs.pari + sage: to_R(e1 + e2) == to_R(e1) + to_R(e2) # optional - sage.rings.finite_rings True - sage: to_R(e1).parent() is R # optional - sage.libs.pari + sage: to_R(e1).parent() is R # optional - sage.rings.finite_rings True - sage: to_R(e2).parent() is R # optional - sage.libs.pari + sage: to_R(e2).parent() is R # optional - sage.rings.finite_rings True sage: F. = FunctionField(QQ) @@ -251,32 +251,32 @@ def _residue_field_global(self, q, name=None): EXAMPLES:: - sage: k. = GF(4) # optional - sage.libs.pari - sage: F. = FunctionField(k) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O._ring # optional - sage.libs.pari + sage: k. = GF(4) # optional - sage.rings.finite_rings + sage: F. = FunctionField(k) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: O._ring # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field in a of size 2^2 - sage: f = x^3 + x + 1 # optional - sage.libs.pari - sage: _f = f.numerator() # optional - sage.libs.pari - sage: _f.is_irreducible() # optional - sage.libs.pari + sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings + sage: _f = f.numerator() # optional - sage.rings.finite_rings + sage: _f.is_irreducible() # optional - sage.rings.finite_rings True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules - sage: K # optional - sage.libs.pari sage.modules + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.rings.finite_rings sage.modules + sage: K # optional - sage.rings.finite_rings sage.modules Finite Field in z6 of size 2^6 - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.rings.finite_rings sage.modules True - sage: k. = GF(2) # optional - sage.libs.pari - sage: F. = FunctionField(k) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: O._ring # optional - sage.libs.pari + sage: k. = GF(2) # optional - sage.rings.finite_rings + sage: F. = FunctionField(k) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: O._ring # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: f = x^3 + x + 1 # optional - sage.libs.pari - sage: _f = f.numerator() # optional - sage.libs.pari - sage: _f.is_irreducible() # optional - sage.libs.pari + sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings + sage: _f = f.numerator() # optional - sage.rings.finite_rings + sage: _f.is_irreducible() # optional - sage.rings.finite_rings True - sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.libs.pari sage.modules - sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.libs.pari sage.modules + sage: K, fr_K, to_K = O._residue_field_global(_f) # optional - sage.rings.finite_rings sage.modules + sage: all(to_K(fr_K(e)) == e for e in K) # optional - sage.rings.finite_rings sage.modules True """ @@ -337,9 +337,9 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: O.basis() # optional - sage.rings.finite_rings (1,) """ return self._basis @@ -425,9 +425,9 @@ class FunctionFieldMaximalOrderInfinite_rational(FunctionFieldMaximalOrderInfini EXAMPLES:: - sage: K. = FunctionField(GF(19)); K # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)); K # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 19 - sage: R = K.maximal_order_infinite(); R # optional - sage.libs.pari + sage: R = K.maximal_order_infinite(); R # optional - sage.rings.finite_rings Maximal infinite order of Rational function field in t over Finite Field of size 19 """ def __init__(self, field, category=None): @@ -436,9 +436,9 @@ def __init__(self, field, category=None): TESTS:: - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order_infinite() # optional - sage.libs.pari - sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd') # optional - sage.rings.finite_rings """ FunctionFieldMaximalOrderInfinite.__init__(self, field, ideal_class=FunctionFieldIdealInfinite_rational, category=PrincipalIdealDomains().or_subcategory(category)) @@ -476,9 +476,9 @@ def basis(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order() # optional - sage.libs.pari - sage: O.basis() # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order() # optional - sage.rings.finite_rings + sage: O.basis() # optional - sage.rings.finite_rings (1,) """ return 1/self.function_field().gen() @@ -518,9 +518,9 @@ def prime_ideal(self): EXAMPLES:: - sage: K. = FunctionField(GF(19)) # optional - sage.libs.pari - sage: O = K.maximal_order_infinite() # optional - sage.libs.pari - sage: O.prime_ideal() # optional - sage.libs.pari + sage: K. = FunctionField(GF(19)) # optional - sage.rings.finite_rings + sage: O = K.maximal_order_infinite() # optional - sage.rings.finite_rings + sage: O.prime_ideal() # optional - sage.rings.finite_rings Ideal (1/t) of Maximal infinite order of Rational function field in t over Finite Field of size 19 """ diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index faf30816da4..685af63a571 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -11,9 +11,9 @@ All rational places of a function field can be computed:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: L.places() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.places() # optional - sage.rings.finite_rings sage.rings.function_field [Place (1/x, 1/x^3*y^2 + 1/x), Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1), Place (x, y)] @@ -21,20 +21,20 @@ The residue field associated with a place is given as an extension of the constant field:: - sage: F. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.libs.pari - sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari + sage: F. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings + sage: p = O.ideal(x^2 + x + 1).place() # optional - sage.rings.finite_rings + sage: k, fr_k, to_k = p.residue_field() # optional - sage.rings.finite_rings + sage: k # optional - sage.rings.finite_rings Finite Field in z2 of size 2^2 The homomorphisms are between the valuation ring and the residue field:: - sage: fr_k # optional - sage.libs.pari + sage: fr_k # optional - sage.rings.finite_rings Ring morphism: From: Finite Field in z2 of size 2^2 To: Valuation ring at Place (x^2 + x + 1) - sage: to_k # optional - sage.libs.pari + sage: to_k # optional - sage.rings.finite_rings Ring morphism: From: Valuation ring at Place (x^2 + x + 1) To: Finite Field in z2 of size 2^2 @@ -77,9 +77,9 @@ class FunctionFieldPlace(Element): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field Place (x, y) """ def __init__(self, parent, prime): @@ -88,10 +88,10 @@ def __init__(self, parent, prime): TESTS:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(p).run() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(p).run() # optional - sage.rings.finite_rings sage.rings.function_field """ Element.__init__(self, parent) @@ -103,10 +103,10 @@ def __hash__(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: {p: 1} # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: {p: 1} # optional - sage.rings.finite_rings sage.rings.function_field {Place (x, y): 1} """ return hash((self.function_field(), self._prime)) @@ -117,10 +117,10 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: p # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p # optional - sage.rings.finite_rings sage.rings.function_field Place (x, y) """ try: @@ -136,10 +136,10 @@ def _latex_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places_finite()[0] # optional - sage.libs.pari sage.rings.function_field - sage: latex(p) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: latex(p) # optional - sage.rings.finite_rings sage.rings.function_field \left(y\right) """ return self._prime._latex_() @@ -150,14 +150,14 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.libs.pari sage.rings.function_field - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field - sage: p1 < p2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x + x^3*Y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1 < p2 # optional - sage.rings.finite_rings sage.rings.function_field True - sage: p2 < p1 # optional - sage.libs.pari sage.rings.function_field + sage: p2 < p1 # optional - sage.rings.finite_rings sage.rings.function_field False - sage: p1 == p3 # optional - sage.libs.pari sage.rings.function_field + sage: p1 == p3 # optional - sage.rings.finite_rings sage.rings.function_field False """ from sage.rings.function_field.order import FunctionFieldOrderInfinite @@ -176,12 +176,12 @@ def _acted_upon_(self, other, self_on_left): EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari sage.rings.function_field - sage: P = I.place() # optional - sage.libs.pari sage.rings.function_field - sage: -3*P + 5*P # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.rings.finite_rings + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(x + 1, y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: P = I.place() # optional - sage.rings.finite_rings sage.rings.function_field + sage: -3*P + 5*P # optional - sage.rings.finite_rings sage.rings.function_field 2*Place (x + 1, y) """ if self_on_left: @@ -194,10 +194,10 @@ def _neg_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field - sage: -p1 + p2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.rings.finite_rings sage.rings.function_field + sage: -p1 + p2 # optional - sage.rings.finite_rings sage.rings.function_field - Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -210,10 +210,10 @@ def _add_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p1, p2, p3 = L.places()[:3] # optional - sage.libs.pari sage.rings.function_field - sage: p1 + p2 + p3 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1, p2, p3 = L.places()[:3] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1 + p2 + p3 # optional - sage.rings.finite_rings sage.rings.function_field Place (1/x, 1/x^3*y^2 + 1/x) + Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) + Place (x, y) @@ -227,10 +227,10 @@ def _sub_(self, other): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p1, p2 = L.places()[:2] # optional - sage.libs.pari sage.rings.function_field - sage: p1 - p2 # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1, p2 = L.places()[:2] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p1 - p2 # optional - sage.rings.finite_rings sage.rings.function_field Place (1/x, 1/x^3*y^2 + 1/x) - Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1) """ @@ -246,14 +246,14 @@ def __radd__(self, other): EXAMPLES:: - sage: k. = GF(2) # optional - sage.libs.pari - sage: K. = FunctionField(k) # optional - sage.libs.pari - sage: sum(K.places_finite()) # optional - sage.libs.pari + sage: k. = GF(2) # optional - sage.rings.finite_rings + sage: K. = FunctionField(k) # optional - sage.rings.finite_rings + sage: sum(K.places_finite()) # optional - sage.rings.finite_rings Place (x) + Place (x + 1) Note that this does not work, as wanted:: - sage: 0 + K.place_infinite() # optional - sage.libs.pari + sage: 0 + K.place_infinite() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: ... @@ -272,10 +272,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places()[0] # optional - sage.libs.pari sage.rings.function_field - sage: p.function_field() == L # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p.function_field() == L # optional - sage.rings.finite_rings sage.rings.function_field True """ return self.parent()._field @@ -286,10 +286,10 @@ def prime_ideal(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: p = L.places()[0] # optional - sage.libs.pari sage.rings.function_field - sage: p.prime_ideal() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: p = L.places()[0] # optional - sage.rings.finite_rings sage.rings.function_field + sage: p.prime_ideal() # optional - sage.rings.finite_rings sage.rings.function_field Ideal (1/x^3*y^2 + 1/x) of Maximal infinite order of Function field in y defined by y^3 + x^3*y + x """ @@ -301,12 +301,12 @@ def divisor(self, multiplicity=1): EXAMPLES:: - sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.libs.pari - sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.libs.pari sage.rings.function_field - sage: O = F.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: I = O.ideal(x + 1, y) # optional - sage.libs.pari sage.rings.function_field - sage: P = I.place() # optional - sage.libs.pari sage.rings.function_field - sage: P.divisor() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(5)); R. = PolynomialRing(K) # optional - sage.rings.finite_rings + sage: F. = K.extension(Y^2 - x^3 - 1) # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = F.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: I = O.ideal(x + 1, y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: P = I.place() # optional - sage.rings.finite_rings sage.rings.function_field + sage: P.divisor() # optional - sage.rings.finite_rings sage.rings.function_field Place (x + 1, y) """ from .divisor import prime_divisor @@ -323,9 +323,9 @@ class PlaceSet(UniqueRepresentation, Parent): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field Set of places of Function field in y defined by y^3 + x^3*y + x """ Element = FunctionFieldPlace @@ -336,10 +336,10 @@ def __init__(self, field): TESTS:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field - sage: TestSuite(places).run() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: places = L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field + sage: TestSuite(places).run() # optional - sage.rings.finite_rings sage.rings.function_field """ self.Element = field._place_class Parent.__init__(self, category = Sets().Infinite()) @@ -352,9 +352,9 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: L.place_set() # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field Set of places of Function field in y defined by y^3 + x^3*y + x """ return "Set of places of {}".format(self._field) @@ -365,11 +365,11 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field - sage: O = L.maximal_order() # optional - sage.libs.pari sage.rings.function_field - sage: places(O.ideal(x, y)) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: places = L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field + sage: O = L.maximal_order() # optional - sage.rings.finite_rings sage.rings.function_field + sage: places(O.ideal(x, y)) # optional - sage.rings.finite_rings sage.rings.function_field Place (x, y) """ from .ideal import FunctionFieldIdeal @@ -385,10 +385,10 @@ def _an_element_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: places = L.place_set() # optional - sage.libs.pari sage.rings.function_field - sage: places.an_element() # random # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: places = L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field + sage: places.an_element() # random # optional - sage.rings.finite_rings sage.rings.function_field Ideal (x) of Maximal order of Rational function field in x over Finite Field of size 2 """ @@ -408,10 +408,10 @@ def function_field(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari sage.rings.function_field - sage: PS = L.place_set() # optional - sage.libs.pari sage.rings.function_field - sage: PS.function_field() == L # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: PS = L.place_set() # optional - sage.rings.finite_rings sage.rings.function_field + sage: PS.function_field() == L # optional - sage.rings.finite_rings sage.rings.function_field True """ return self._field diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index 5615a17c0f0..4aec53fe34b 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -28,14 +28,14 @@ def place_below(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.place_below() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: OK = K.maximal_order() # optional - sage.rings.finite_rings + sage: OL = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: dec = OL.decomposition(p) # optional - sage.rings.finite_rings + sage: q = dec[0][0].place() # optional - sage.rings.finite_rings + sage: q.place_below() # optional - sage.rings.finite_rings Place (x^2 + x + 1) """ return self.prime_ideal().prime_below().place() @@ -46,14 +46,14 @@ def relative_degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.relative_degree() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: OK = K.maximal_order() # optional - sage.rings.finite_rings + sage: OL = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: dec = OL.decomposition(p) # optional - sage.rings.finite_rings + sage: q = dec[0][0].place() # optional - sage.rings.finite_rings + sage: q.relative_degree() # optional - sage.rings.finite_rings 1 """ return self._prime._relative_degree @@ -64,14 +64,14 @@ def degree(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: OK = K.maximal_order() # optional - sage.libs.pari - sage: OL = L.maximal_order() # optional - sage.libs.pari - sage: p = OK.ideal(x^2 + x + 1) # optional - sage.libs.pari - sage: dec = OL.decomposition(p) # optional - sage.libs.pari - sage: q = dec[0][0].place() # optional - sage.libs.pari - sage: q.degree() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: OK = K.maximal_order() # optional - sage.rings.finite_rings + sage: OL = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = OK.ideal(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: dec = OL.decomposition(p) # optional - sage.rings.finite_rings + sage: q = dec[0][0].place() # optional - sage.rings.finite_rings + sage: q.degree() # optional - sage.rings.finite_rings 2 """ return self.relative_degree() * self.place_below().degree() @@ -83,12 +83,12 @@ def is_infinite_place(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: pls = L.places() # optional - sage.libs.pari - sage: [p.is_infinite_place() for p in pls] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: pls = L.places() # optional - sage.rings.finite_rings + sage: [p.is_infinite_place() for p in pls] # optional - sage.rings.finite_rings [True, True, False] - sage: [p.place_below() for p in pls] # optional - sage.libs.pari + sage: [p.place_below() for p in pls] # optional - sage.rings.finite_rings [Place (1/x), Place (1/x), Place (x)] """ return self.place_below().is_infinite_place() @@ -100,10 +100,10 @@ def local_uniformizer(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: pls = L.places() # optional - sage.libs.pari - sage: [p.local_uniformizer().valuation(p) for p in pls] # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: pls = L.places() # optional - sage.rings.finite_rings + sage: [p.local_uniformizer().valuation(p) for p in pls] # optional - sage.rings.finite_rings [1, 1, 1, 1, 1] """ gens = self._prime.gens() @@ -118,16 +118,16 @@ def gaps(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x,y).place() # optional - sage.libs.pari - sage: p.gaps() # a Weierstrass place # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = O.ideal(x,y).place() # optional - sage.rings.finite_rings + sage: p.gaps() # a Weierstrass place # optional - sage.rings.finite_rings [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: [p.gaps() for p in L.places()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.rings.finite_rings + sage: [p.gaps() for p in L.places()] # optional - sage.rings.finite_rings [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ if self.degree() == 1: @@ -145,16 +145,16 @@ def _gaps_rational(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x, y).place() # optional - sage.libs.pari - sage: p.gaps() # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = O.ideal(x, y).place() # optional - sage.rings.finite_rings + sage: p.gaps() # indirect doctest # optional - sage.rings.finite_rings [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: [p.gaps() for p in L.places()] # indirect doctest # optional - sage.rings.finite_rings [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ from sage.matrix.constructor import matrix @@ -276,16 +276,16 @@ def _gaps_wronskian(self): EXAMPLES:: - sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.libs.pari - sage: O = L.maximal_order() # optional - sage.libs.pari - sage: p = O.ideal(x, y).place() # optional - sage.libs.pari - sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.libs.pari + sage: K. = FunctionField(GF(4)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3*Y + x) # optional - sage.rings.finite_rings + sage: O = L.maximal_order() # optional - sage.rings.finite_rings + sage: p = O.ideal(x, y).place() # optional - sage.rings.finite_rings + sage: p._gaps_wronskian() # a Weierstrass place # optional - sage.rings.finite_rings [1, 2, 4] - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.libs.pari - sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + x^3 * Y + x) # optional - sage.rings.finite_rings + sage: [p._gaps_wronskian() for p in L.places()] # optional - sage.rings.finite_rings [[1, 2, 4], [1, 2, 4], [1, 2, 4]] """ from sage.matrix.constructor import matrix @@ -339,28 +339,28 @@ def residue_field(self, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: k, fr_k, to_k = p.residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings + sage: k, fr_k, to_k = p.residue_field() # optional - sage.rings.finite_rings + sage: k # optional - sage.rings.finite_rings Finite Field of size 2 - sage: fr_k # optional - sage.libs.pari + sage: fr_k # optional - sage.rings.finite_rings Ring morphism: From: Finite Field of size 2 To: Valuation ring at Place (x, x*y) - sage: to_k # optional - sage.libs.pari + sage: to_k # optional - sage.rings.finite_rings Ring morphism: From: Valuation ring at Place (x, x*y) To: Finite Field of size 2 - sage: to_k(y) # optional - sage.libs.pari + sage: to_k(y) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: y fails to convert into the map's domain Valuation ring at Place (x, x*y)... - sage: to_k(1/y) # optional - sage.libs.pari + sage: to_k(1/y) # optional - sage.rings.finite_rings 0 - sage: to_k(y/(1+y)) # optional - sage.libs.pari + sage: to_k(y/(1+y)) # optional - sage.rings.finite_rings 1 """ return self.valuation_ring().residue_field(name=name) @@ -378,21 +378,21 @@ def _residue_field(self, name=None): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: k,fr_k,to_k = p._residue_field() # optional - sage.libs.pari - sage: k # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings + sage: k,fr_k,to_k = p._residue_field() # optional - sage.rings.finite_rings + sage: k # optional - sage.rings.finite_rings Finite Field of size 2 - sage: [fr_k(e) for e in k] # optional - sage.libs.pari + sage: [fr_k(e) for e in k] # optional - sage.rings.finite_rings [0, 1] :: - sage: K. = FunctionField(GF(9)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.libs.pari - sage: p = L.places()[-1] # optional - sage.libs.pari - sage: p.residue_field() # optional - sage.libs.pari + sage: K. = FunctionField(GF(9)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^3 + Y - x^4) # optional - sage.rings.finite_rings + sage: p = L.places()[-1] # optional - sage.rings.finite_rings + sage: p.residue_field() # optional - sage.rings.finite_rings (Finite Field in z2 of size 3^2, Ring morphism: From: Finite Field in z2 of size 3^2 To: Valuation ring at Place (x + 1, y + 2*z2), Ring morphism: @@ -651,10 +651,10 @@ def valuation_ring(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.libs.pari - sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.libs.pari - sage: p = L.places_finite()[0] # optional - sage.libs.pari - sage: p.valuation_ring() # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)); _. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(Y^2 + Y + x + 1/x) # optional - sage.rings.finite_rings + sage: p = L.places_finite()[0] # optional - sage.rings.finite_rings + sage: p.valuation_ring() # optional - sage.rings.finite_rings Valuation ring at Place (x, x*y) """ from .valuation_ring import FunctionFieldValuationRing diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py index df0ad509c9c..c9cea4b1097 100644 --- a/src/sage/rings/function_field/place_rational.py +++ b/src/sage/rings/function_field/place_rational.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari (because all doctests use finite fields) +# sage.doctest: optional - sage.rings.finite_rings (because all doctests use finite fields) #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py index 420f47a43e3..022103e096d 100644 --- a/src/sage/rings/function_field/valuation.py +++ b/src/sage/rings/function_field/valuation.py @@ -77,10 +77,10 @@ Run test suite for some other classical places over large ground fields:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: M. = FunctionField(K) # optional - sage.libs.pari - sage: v = M.valuation(x^3 - t) # optional - sage.libs.pari - sage: TestSuite(v).run(max_runs=10) # long time # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: M. = FunctionField(K) # optional - sage.rings.finite_rings + sage: v = M.valuation(x^3 - t) # optional - sage.rings.finite_rings + sage: TestSuite(v).run(max_runs=10) # long time # optional - sage.rings.finite_rings Run test suite for extensions over the infinite place:: @@ -111,9 +111,9 @@ Run test suite for a finite place with residual degree and ramification:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: L. = FunctionField(K) # optional - sage.libs.pari - sage: v = L.valuation(x^6 - t) # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: L. = FunctionField(K) # optional - sage.rings.finite_rings + sage: v = L.valuation(x^6 - t) # optional - sage.rings.finite_rings sage: TestSuite(v).run(max_runs=10) # long time Run test suite for a valuation which is backed by limit valuation:: @@ -350,11 +350,11 @@ def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, v TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.rings.function_field - sage: w = v.extension(L) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = v.extension(L) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field """ from sage.categories.function_fields import FunctionFields @@ -508,14 +508,14 @@ def extensions(self, L): Iterated extensions over the infinite place:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field - sage: M. = L.extension(z^2 - y) # optional - sage.libs.pari sage.rings.function_field - sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: R. = L[] # optional - sage.rings.finite_rings sage.rings.function_field + sage: M. = L.extension(z^2 - y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.extension(M) # squarefreeness is not implemented here # optional - sage.rings.finite_rings sage.rings.function_field Traceback (most recent call last): ... NotImplementedError @@ -535,13 +535,13 @@ def extensions(self, L): Test that this works in towers:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y - x) # optional - sage.libs.pari sage.rings.function_field - sage: R. = L[] # optional - sage.libs.pari sage.rings.function_field - sage: L. = L.extension(z - y) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(x) # optional - sage.libs.pari sage.rings.function_field - sage: v.extensions(L) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y - x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: R. = L[] # optional - sage.rings.finite_rings sage.rings.function_field + sage: L. = L.extension(z - y) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v.extensions(L) # optional - sage.rings.finite_rings sage.rings.function_field [(x)-adic valuation] """ K = self.domain() @@ -586,10 +586,10 @@ class RationalFunctionFieldValuation_base(FunctionFieldValuation_base): TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: v = K.valuation(x) # indirect doctest # optional - sage.rings.finite_rings sage: from sage.rings.function_field.valuation import RationalFunctionFieldValuation_base - sage: isinstance(v, RationalFunctionFieldValuation_base) # optional - sage.libs.pari + sage: isinstance(v, RationalFunctionFieldValuation_base) # optional - sage.rings.finite_rings True """ @@ -629,10 +629,10 @@ class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base): TESTS:: - sage: K. = FunctionField(GF(5)) # optional - sage.libs.pari - sage: v = K.valuation(x) # indirect doctest # optional - sage.libs.pari + sage: K. = FunctionField(GF(5)) # optional - sage.rings.finite_rings + sage: v = K.valuation(x) # indirect doctest # optional - sage.rings.finite_rings sage: from sage.rings.function_field.valuation import ClassicalFunctionFieldValuation_base - sage: isinstance(v, ClassicalFunctionFieldValuation_base) # optional - sage.libs.pari + sage: isinstance(v, ClassicalFunctionFieldValuation_base) # optional - sage.rings.finite_rings True """ @@ -997,14 +997,14 @@ class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation A finite place with ramification:: - sage: K. = FunctionField(GF(3)) # optional - sage.libs.pari - sage: L. = FunctionField(K) # optional - sage.libs.pari - sage: u = L.valuation(x^3 - t); u # optional - sage.libs.pari + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: L. = FunctionField(K) # optional - sage.rings.finite_rings + sage: u = L.valuation(x^3 - t); u # optional - sage.rings.finite_rings (x^3 + 2*t)-adic valuation A finite place with residual degree and ramification:: - sage: q = L.valuation(x^6 - t); q # optional - sage.libs.pari + sage: q = L.valuation(x^6 - t); q # optional - sage.rings.finite_rings (x^6 + 2*t)-adic valuation """ @@ -1175,8 +1175,8 @@ class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValua EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x); v # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: v = K.valuation(1/x); v # optional - sage.rings.finite_rings Valuation at the infinite place """ @@ -1184,10 +1184,10 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v r""" TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuation_base - sage: isinstance(v, FunctionFieldMappedValuation_base) # optional - sage.libs.pari + sage: isinstance(v, FunctionFieldMappedValuation_base) # optional - sage.rings.finite_rings True """ @@ -1203,12 +1203,12 @@ def _to_base_domain(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: w._to_base_domain(y) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w._to_base_domain(y) # optional - sage.rings.finite_rings sage.rings.function_field x^2*y """ @@ -1220,12 +1220,12 @@ def _from_base_domain(self, f): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w._from_base_domain(w._to_base_domain(y)) # optional - sage.rings.finite_rings sage.rings.function_field y r""" @@ -1237,12 +1237,12 @@ def scale(self, scalar): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: 3*w # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: 3*w # optional - sage.rings.finite_rings sage.rings.function_field 3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x) """ @@ -1257,11 +1257,11 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: v.extension(L) # indirect doctest # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: v.extension(L) # indirect doctest # optional - sage.rings.finite_rings sage.rings.function_field Valuation at the infinite place """ @@ -1296,8 +1296,8 @@ class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_bas EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x); v # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: v = K.valuation(1/x); v # optional - sage.rings.finite_rings Valuation at the infinite place """ @@ -1305,10 +1305,10 @@ def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_v r""" TESTS:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: v = K.valuation(1/x) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuationRelative_base - sage: isinstance(v, FunctionFieldMappedValuationRelative_base) # optional - sage.libs.pari + sage: isinstance(v, FunctionFieldMappedValuationRelative_base) # optional - sage.rings.finite_rings True """ @@ -1322,8 +1322,8 @@ def restriction(self, ring): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: K.valuation(1/x).restriction(GF(2)) # optional - sage.libs.pari + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: K.valuation(1/x).restriction(GF(2)) # optional - sage.rings.finite_rings Trivial valuation on Finite Field of size 2 """ @@ -1417,23 +1417,23 @@ class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field - sage: w(x) # optional - sage.libs.pari sage.rings.function_field + sage: w(x) # optional - sage.rings.finite_rings sage.rings.function_field -1 - sage: w(y) # optional - sage.libs.pari sage.rings.function_field + sage: w(y) # optional - sage.rings.finite_rings sage.rings.function_field -3/2 - sage: w.uniformizer() # optional - sage.libs.pari sage.rings.function_field + sage: w.uniformizer() # optional - sage.rings.finite_rings sage.rings.function_field 1/x^2*y TESTS:: sage: from sage.rings.function_field.valuation import FunctionFieldExtensionMappedValuation - sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.libs.pari sage.rings.function_field + sage: isinstance(w, FunctionFieldExtensionMappedValuation) # optional - sage.rings.finite_rings sage.rings.function_field True """ @@ -1443,11 +1443,11 @@ def _repr_(self): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari sage.rings.function_field - sage: w = v.extension(L); w # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w = v.extension(L); w # optional - sage.rings.finite_rings sage.rings.function_field Valuation at the infinite place sage: K. = FunctionField(QQ) @@ -1470,12 +1470,12 @@ def restriction(self, ring): EXAMPLES:: - sage: K. = FunctionField(GF(2)) # optional - sage.libs.pari - sage: R. = K[] # optional - sage.libs.pari - sage: L. = K.extension(y^2 + y + x^3) # optional - sage.libs.pari sage.rings.function_field - sage: v = K.valuation(1/x) # optional - sage.libs.pari - sage: w = v.extension(L) # optional - sage.libs.pari sage.rings.function_field - sage: w.restriction(K) is v # optional - sage.libs.pari sage.rings.function_field + sage: K. = FunctionField(GF(2)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(y^2 + y + x^3) # optional - sage.rings.finite_rings sage.rings.function_field + sage: v = K.valuation(1/x) # optional - sage.rings.finite_rings + sage: w = v.extension(L) # optional - sage.rings.finite_rings sage.rings.function_field + sage: w.restriction(K) is v # optional - sage.rings.finite_rings sage.rings.function_field True """ if ring.is_subring(self.domain().base()): diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index f408d2b4b38..37d111df2c8 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: optional - sage.rings.finite_rings # sage.doctest: optional - sage.rings.function_field r""" Valuation rings of function fields From 7c4e35dd9cbfaf3e887a2dec05792e5cc38dd34d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 17:20:51 -0700 Subject: [PATCH 48/54] sage.rings.function_field: Import directly from .order_* --- src/sage/rings/function_field/function_field.py | 4 ++-- src/sage/rings/function_field/function_field_polymod.py | 8 ++++---- src/sage/rings/function_field/function_field_rational.py | 4 ++-- src/sage/rings/function_field/order_basis.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index 76bf62d3a10..e89ea118106 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -495,7 +495,7 @@ def order_with_basis(self, basis, check=True): ... ValueError: the identity element must be in the module spanned by basis (x, x*y + x^2, 2/3*y^2) """ - from .order import FunctionFieldOrder_basis + from .order_basis import FunctionFieldOrder_basis return FunctionFieldOrder_basis(tuple([self(a) for a in basis]), check=check) def order(self, x, check=True): @@ -586,7 +586,7 @@ def order_infinite_with_basis(self, basis, check=True): ... ValueError: the identity element must be in the module spanned by basis (1/x, 1/x*y, 1/x^2*y^2) """ - from .order import FunctionFieldOrderInfinite_basis + from .order_basis import FunctionFieldOrderInfinite_basis return FunctionFieldOrderInfinite_basis(tuple([self(g) for g in basis]), check=check) def order_infinite(self, x, check=True): diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 3ecf29dfdee..28756a62cf6 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -784,7 +784,7 @@ def maximal_order(self): sage: L.maximal_order() Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x """ - from .order import FunctionFieldMaximalOrder_polymod + from .order_polymod import FunctionFieldMaximalOrder_polymod return FunctionFieldMaximalOrder_polymod(self) def maximal_order_infinite(self): @@ -808,7 +808,7 @@ def maximal_order_infinite(self): sage: L.maximal_order_infinite() # optional - sage.rings.finite_rings Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x """ - from .order import FunctionFieldMaximalOrderInfinite_polymod + from .order_polymod import FunctionFieldMaximalOrderInfinite_polymod return FunctionFieldMaximalOrderInfinite_polymod(self) def different(self): @@ -2459,7 +2459,7 @@ def equation_order(self): sage: F.equation_order() Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ - from .order import FunctionFieldOrder_basis + from .order_basis import FunctionFieldOrder_basis a = self.gen() basis = [a**i for i in range(self.degree())] return FunctionFieldOrder_basis(tuple(basis)) @@ -2512,7 +2512,7 @@ def equation_order_infinite(self): sage: F.equation_order_infinite() Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2 """ - from .order import FunctionFieldOrderInfinite_basis + from .order_basis import FunctionFieldOrderInfinite_basis b = self.primitive_integal_element_infinite() basis = [b**i for i in range(self.degree())] return FunctionFieldOrderInfinite_basis(tuple(basis)) diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index 9155e9539b6..de84df46d6a 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -701,7 +701,7 @@ def maximal_order(self): sage: K.equation_order() Maximal order of Rational function field in t over Rational Field """ - from .order import FunctionFieldMaximalOrder_rational + from .order_rational import FunctionFieldMaximalOrder_rational return FunctionFieldMaximalOrder_rational(self) equation_order = maximal_order @@ -722,7 +722,7 @@ def maximal_order_infinite(self): sage: K.equation_order_infinite() Maximal infinite order of Rational function field in t over Rational Field """ - from .order import FunctionFieldMaximalOrderInfinite_rational + from .order_rational import FunctionFieldMaximalOrderInfinite_rational return FunctionFieldMaximalOrderInfinite_rational(self) equation_order_infinite = maximal_order_infinite diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index f3428cf9e3b..918a1e44496 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -56,7 +56,7 @@ class FunctionFieldOrder_basis(FunctionFieldOrder): Traceback (most recent call last): ... ValueError: basis (1, x, x^2, x^3, x^4) is not linearly independent - sage: sage.rings.function_field.order.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.rings.function_field + sage: sage.rings.function_field.order_basis.FunctionFieldOrder_basis((y,y,y^3,y^4,y^5)) # optional - sage.rings.function_field Traceback (most recent call last): ... ValueError: basis (y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x) is not linearly independent From 3f098a0e6c8a8464bd104928bfeab6c18addce83 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 17:21:32 -0700 Subject: [PATCH 49/54] sage.rings.function_field: Remove unnecessary lazy imports for internal classes --- src/sage/rings/function_field/maps.py | 6 ------ src/sage/rings/function_field/order.py | 10 ---------- 2 files changed, 16 deletions(-) diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 0a4e178dff1..ce0a775c31e 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -60,13 +60,7 @@ lazy_import("sage.rings.function_field.derivations", ( "FunctionFieldDerivation", - "FunctionFieldDerivation_rational", - "FunctionFieldDerivation_separable", - "FunctionFieldDerivation_inseparable", "FunctionFieldHigherDerivation", - "RationalFunctionFieldHigherDerivation_global", - "FunctionFieldHigherDerivation_global", - "FunctionFieldHigherDerivation_char_zero", ), deprecation=35230) diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index d44c6513829..a2e85f21fc8 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -109,21 +109,11 @@ #***************************************************************************** from sage.categories.integral_domains import IntegralDomains -from sage.misc.lazy_import import lazy_import from sage.structure.parent import Parent from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation from .ideal import IdealMonoid, FunctionFieldIdeal -lazy_import('sage.rings.function_field.order_basis', - ['FunctionFieldOrder_basis', 'FunctionFieldOrderInfinite_basis']) -lazy_import('sage.rings.function_field.order_rational', - ['FunctionFieldMaximalOrder_rational', 'FunctionFieldMaximalOrderInfinite_rational']) -lazy_import('sage.rings.function_field.order_polymod', - ['FunctionFieldMaximalOrder_polymod', 'FunctionFieldMaximalOrderInfinite_polymod']) -lazy_import('sage.rings.function_field.order_global', - ['FunctionFieldMaximalOrder_global']) - class FunctionFieldOrder_base(CachedRepresentation, Parent): """ From 7f12a8ee901f6fe64a8a7cc525560779f7aa2896 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 18:09:20 -0700 Subject: [PATCH 50/54] src/doc/en/developer/packaging_sage_library.rst: Add best practices for # optional - sage... --- src/doc/en/developer/packaging_sage_library.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index 7e7a5cde56f..229c3dc01d7 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -567,6 +567,15 @@ doctests that depend on :class:`sage.symbolic.ring.SymbolicRing` for integration testing. Hence, these doctests are marked ``# optional - sage.symbolic``. +When defining new features for the purpose of doctest annotations, it may be a good +idea to hide implementation details from feature names. For example, all doctests that +use finite fields have to depend on PARI. However, we have defined a feature +:mod:`sage.rings.finite_rings` (which implies the presence of :mod:`sage.libs.pari`). +Annotating the doctests ``# optional - sage.rings.finite_rings`` expresses the +dependency in a clearer way than using ``# optional - sage.libs.pari``, and it +will be a smaller maintenance burden when implementation details change. + + Testing the distribution in virtual environments with tox --------------------------------------------------------- From 97894ee629e1afeef311bbe218e1c52efe02799e Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 19 Mar 2023 21:42:36 +0900 Subject: [PATCH 51/54] Add missing titles to new files --- src/sage/rings/function_field/derivations_polymod.py | 4 ++++ src/sage/rings/function_field/derivations_rational.py | 4 ++++ src/sage/rings/function_field/element_polymod.pyx | 3 +++ src/sage/rings/function_field/element_rational.pyx | 3 +++ src/sage/rings/function_field/ideal_polymod.py | 3 +++ src/sage/rings/function_field/ideal_rational.py | 4 ++++ src/sage/rings/function_field/order_basis.py | 2 +- src/sage/rings/function_field/order_polymod.py | 3 +-- src/sage/rings/function_field/order_rational.py | 2 +- src/sage/rings/function_field/place_polymod.py | 3 +++ src/sage/rings/function_field/place_rational.py | 3 +++ 11 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/function_field/derivations_polymod.py b/src/sage/rings/function_field/derivations_polymod.py index 4d05cc98982..cc23d4c2461 100644 --- a/src/sage/rings/function_field/derivations_polymod.py +++ b/src/sage/rings/function_field/derivations_polymod.py @@ -1,3 +1,7 @@ +r""" +Derivations of function fields: extension +""" + # **************************************************************************** # Copyright (C) 2010 William Stein # 2011-2017 Julian Rüth diff --git a/src/sage/rings/function_field/derivations_rational.py b/src/sage/rings/function_field/derivations_rational.py index 8b0fbc36032..777f16d3e08 100644 --- a/src/sage/rings/function_field/derivations_rational.py +++ b/src/sage/rings/function_field/derivations_rational.py @@ -1,3 +1,7 @@ +r""" +Derivations of function fields: rational +""" + # **************************************************************************** # Copyright (C) 2010 William Stein # 2011-2017 Julian Rüth diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index f456af74268..c5ea5670591 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -1,4 +1,7 @@ # sage.doctest: optional - sage.rings.function_field +r""" +Elements of function fields: extension +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index 5d5f8857004..76656e1735a 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -1,3 +1,6 @@ +r""" +Elements of function fields: rational +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index 671a20fb434..b105c6047b1 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -1,4 +1,7 @@ # sage.doctest: optional - sage.rings.function_field +r""" +Ideals of function fields: extension +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 61cf36777c6..9f110034c55 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -1,3 +1,7 @@ +r""" +Ideals of function fields: rational +""" + #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee # diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index 918a1e44496..bb9ffd72979 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -1,7 +1,7 @@ # sage.doctest: optional - sage.modules (because __init__ constructs a vector space) # some tests are marked # optional - sage.rings.finite_rings (because they use finite fields) r""" -Orders of function fields given by a basis over the maximal order of the base field +Orders of function fields: basis """ #***************************************************************************** diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 0026786fa09..66f6fb4b3db 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -1,7 +1,6 @@ # sage.doctest: optional - sage.rings.function_field - r""" -Orders of function fields - polymod implementation +Orders of function fields: extension """ #***************************************************************************** diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index 0962cca86ed..d421b64e67e 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -1,5 +1,5 @@ r""" -Orders of rational function fields +Orders of function fields: rational """ #***************************************************************************** diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index 4aec53fe34b..dcba75d7fd3 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -1,4 +1,7 @@ # sage.doctest: optional - sage.rings.function_field +""" +Places of function fields: extension +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py index c9cea4b1097..7a8acd440b6 100644 --- a/src/sage/rings/function_field/place_rational.py +++ b/src/sage/rings/function_field/place_rational.py @@ -1,4 +1,7 @@ # sage.doctest: optional - sage.rings.finite_rings (because all doctests use finite fields) +""" +Places of function fields: rational +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee From 07e34164573ae7aa692630549eed91ad883f6121 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 19 Mar 2023 21:58:40 +0900 Subject: [PATCH 52/54] Add more --- src/doc/en/reference/function_fields/index.rst | 2 ++ src/sage/rings/function_field/function_field_polymod.py | 3 +++ src/sage/rings/function_field/function_field_rational.py | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/doc/en/reference/function_fields/index.rst b/src/doc/en/reference/function_fields/index.rst index cdd34d5ffff..9f9a7e8c42d 100644 --- a/src/doc/en/reference/function_fields/index.rst +++ b/src/doc/en/reference/function_fields/index.rst @@ -11,6 +11,8 @@ algebraic closure of `\QQ`. :maxdepth: 1 sage/rings/function_field/function_field + sage/rings/function_field/function_field_rational + sage/rings/function_field/function_field_polymod sage/rings/function_field/element sage/rings/function_field/element_rational sage/rings/function_field/element_polymod diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 28756a62cf6..76d12423004 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -1,4 +1,7 @@ # sage.doctest: optional - sage.rings.function_field +r""" +Function Fields: extension +""" #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index de84df46d6a..8ada23fec93 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -1,3 +1,7 @@ +r""" +Function Fields: rational +""" + #***************************************************************************** # Copyright (C) 2023 Kwankyu Lee # From bbc19979c5c3c8b83d44aa472ce5baa8bc74f065 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Mar 2023 19:50:31 -0700 Subject: [PATCH 53/54] src/sage/rings/function_field: Fix linter --- src/sage/rings/function_field/element.pyx | 1 - src/sage/rings/function_field/element_polymod.pyx | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 989b0e964e8..2533611cf52 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -718,4 +718,3 @@ cdef class FunctionFieldElement(FieldElement): y """ raise NotImplementedError("nth_root() not implemented for generic elements") - diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index c5ea5670591..2c858f8568c 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -396,5 +396,3 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): f = self._x(y).map_coefficients(lambda c: c.nth_root(char)) return self._parent(f) - - From 999030298cfd998fece7e613f8f3dbd24146f713 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 30 Mar 2023 08:47:27 -0700 Subject: [PATCH 54/54] src/sage/features/standard.py: Remove rpy2 feature for now --- src/sage/features/standard.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index 99028676a20..f48f47f2614 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -31,6 +31,5 @@ def all_features(): PythonModule('primecountpy', spkg='primecountpy'), PythonModule('ptyprocess', spkg='ptyprocess'), PythonModule('requests', spkg='requests'), - PythonModule('rpy2', spkg='rpy2'), PythonModule('scipy', spkg='scipy'), PythonModule('sympy', spkg='sympy')]