Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 44 additions & 11 deletions src/sage/combinat/bijectionist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,30 +1021,51 @@ def set_value_restrictions(self, *value_restrictions):
{[]: 0, [1]: 1, [1, 2]: 1, [2, 1]: 2, [1, 2, 3]: 3, [1, 3, 2]: 2, [2, 1, 3]: 2, [2, 3, 1]: 1, [3, 1, 2]: 2, [3, 2, 1]: 2}
{[]: 0, [1]: 1, [1, 2]: 1, [2, 1]: 2, [1, 2, 3]: 3, [1, 3, 2]: 2, [2, 1, 3]: 2, [2, 3, 1]: 2, [3, 1, 2]: 1, [3, 2, 1]: 2}

However, an error occurs if the set of possible values is
empty. In this example, the image of `\tau` under any
legal bijection is disjoint to the specified values.
A :exc:`ValueError` is raised immediately if the restriction for an
element `a` is empty (i.e., none of the specified values appear in
`Z`). This allows catching typos early, before calling
:meth:`solutions_iterator`. ::

sage: A = [1, 2, 3]
sage: b = Bijectionist(A, A)
sage: b.set_value_restrictions((1, [4]))
Traceback (most recent call last):
...
ValueError: the value restriction for element 1 is empty:
none of the given values [4] lie in Z = {1, 2, 3}

The same check applies when the elements are iterables
(this catches the common mistake of passing a tuple instead of
a list of allowed values)::

sage: A = [(1, 2), (3, 4)]
sage: b = Bijectionist(A, A)
sage: b.set_value_restrictions(((1, 2), (3, 4)))
Traceback (most recent call last):
...
ValueError: the value restriction for element (1, 2) is empty:
none of the given values [(3, 4)] lie in Z = {(1, 2), (3, 4)}

TESTS::

sage: A = B = [permutation for n in range(4) for permutation in Permutations(n)]
sage: tau = Permutation.longest_increasing_subsequence_length
sage: bij = Bijectionist(A, B, tau)
sage: bij.set_value_restrictions((Permutation([1, 2]), [4, 5]))
sage: bij._compute_possible_block_values()
Traceback (most recent call last):
...
ValueError: no possible values found for singleton block [[1, 2]]
ValueError: the value restriction for element [1, 2] is empty:
none of the given values [4, 5] lie in Z = {0, 1, 2, 3, 4}

sage: A = B = [permutation for n in range(4) for permutation in Permutations(n)]
sage: tau = Permutation.longest_increasing_subsequence_length
sage: bij = Bijectionist(A, B, tau)
sage: bij.set_constant_blocks([[permutation for permutation in Permutations(n)] for n in range(4)])
sage: bij.set_value_restrictions((Permutation([1, 2]), [4, 5]))
sage: bij._compute_possible_block_values()
Traceback (most recent call last):
...
ValueError: no possible values found for block [[1, 2], [2, 1]]
ValueError: the value restriction for element [1, 2] is empty:
none of the given values [4, 5] lie in Z = {0, 1, 2, 3, 4}

sage: A = B = [permutation for n in range(4) for permutation in Permutations(n)]
sage: tau = Permutation.longest_increasing_subsequence_length
Expand All @@ -1063,7 +1084,13 @@ def set_value_restrictions(self, *value_restrictions):
self._restrictions_possible_values = {a: set_Z for a in self._A}
for a, values in value_restrictions:
assert a in self._A, f"element {a} was not found in A"
self._restrictions_possible_values[a] = self._restrictions_possible_values[a].intersection(values)
restricted = self._restrictions_possible_values[a].intersection(values)
if not restricted:
raise ValueError(
f"the value restriction for element {a!r} is empty:\n"
f"none of the given values {list(values)} lie in Z = {set_Z}"
)
self._restrictions_possible_values[a] = restricted

def _compute_possible_block_values(self):
r"""
Expand All @@ -1074,16 +1101,22 @@ def _compute_possible_block_values(self):
It raises a :exc:`ValueError`, if the restrictions on a
block are contradictory.

TESTS::
TESTS:

The ``_compute_possible_block_values`` method can still raise
:exc:`ValueError` if conflicting statistics reduce a block's
possible values to the empty set (bypassing the early check in
:meth:`set_value_restrictions`). Here we set the internal
``_restrictions_possible_values`` directly to reproduce that path::

sage: A = B = [permutation for n in range(4) for permutation in Permutations(n)]
sage: tau = Permutation.longest_increasing_subsequence_length
sage: bij = Bijectionist(A, B, tau)
sage: bij.set_value_restrictions((Permutation([1, 2]), [4, 5]))
sage: bij._restrictions_possible_values = {a: set() for a in bij._A}
sage: bij._compute_possible_block_values()
Traceback (most recent call last):
...
ValueError: no possible values found for singleton block [[1, 2]]
ValueError: no possible values found for singleton block [[]]
"""
self._possible_block_values = {} # P -> Power(Z)
for p, block in self._P.root_to_elements_dict().items():
Expand Down
23 changes: 23 additions & 0 deletions src/sage/modules/free_module_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1835,13 +1835,36 @@ cdef class FreeModuleElement(Vector): # abstract base class
sage: v = vector(QQ, [1,2])
sage: v.norm(int(2)) # needs sage.symbolic
sqrt(5)

For vectors in an :class:`~sage.modules.free_quadratic_module_integer_symmetric.FreeQuadraticModule_integer_symmetric`
(e.g. an :func:`~sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice`),
the 2-norm uses the lattice inner product, so ``norm()^2 == inner_product(v, v)``
(see :issue:`38543`)::

sage: from sage.modules.free_quadratic_module_integer_symmetric import IntegralLattice
sage: L = IntegralLattice(matrix([[1000, 0], [0, 1]]))
sage: v = L.0
sage: v.inner_product(v)
1000
sage: v.norm()^2
1000
sage: v.norm()^2 == v.inner_product(v)
True
"""
abs_self = [abs(x) for x in self]
if p == Infinity:
return max(abs_self)
if p < 1:
raise ValueError("%s is not greater than or equal to 1" % p)

if p == 2:
# For IntegralLattice vectors, use the lattice inner product so that
# norm()^2 == inner_product(self, self). See :issue:`38543`.
from sage.modules.free_quadratic_module_integer_symmetric import (
FreeQuadraticModule_integer_symmetric)
if isinstance(self.parent(), FreeQuadraticModule_integer_symmetric):
return self.inner_product(self).sqrt()

s = sum(a ** p for a in abs_self)
return s**(__one__/p)

Expand Down
59 changes: 59 additions & 0 deletions src/sage/modules/free_quadratic_module_integer_symmetric.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
EXAMPLES::

sage: M = Matrix(ZZ, [[0,1], [1,0]])
sage: IntegralLattice(M)

Check failure on line 14 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric[1]>", line 1, in <module> IntegralLattice(M) ~~~~~~~~~~~~~~~^^^ File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
Lattice of degree 2 and rank 2 over Integer Ring
Standard basis
Inner product matrix:
Expand All @@ -23,15 +23,15 @@

sage: G = matrix.identity(3)
sage: basis = [[1,-1,0], [0,1,-1]]
sage: L = IntegralLattice(G, basis)

Check failure on line 26 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric[4]>", line 1, in <module> L = IntegralLattice(G, basis) File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
sage: L

Check failure on line 27 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric[5]>", line 1, in <module> L NameError: name 'L' is not defined
Lattice of degree 3 and rank 2 over Integer Ring
Basis matrix:
[ 1 -1 0]
[ 0 1 -1]
Standard scalar product

sage: L.gram_matrix()

Check failure on line 34 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric[6]>", line 1, in <module> L.gram_matrix() ^ NameError: name 'L' is not defined
[ 2 -1]
[-1 2]

Expand Down Expand Up @@ -103,7 +103,7 @@
EXAMPLES::

sage: H5 = Matrix(ZZ, 2, [2,1,1,-2])
sage: IntegralLattice(H5)

Check failure on line 106 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[1]>", line 1, in <module> IntegralLattice(H5) ~~~~~~~~~~~~~~~^^^^ File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
Lattice of degree 2 and rank 2 over Integer Ring
Standard basis
Inner product matrix:
Expand All @@ -112,7 +112,7 @@

A basis can be specified too::

sage: IntegralLattice(H5, Matrix([1,1]))

Check failure on line 115 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[2]>", line 1, in <module> IntegralLattice(H5, Matrix([Integer(1),Integer(1)])) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
Lattice of degree 2 and rank 1 over Integer Ring
Basis matrix:
[1 1]
Expand All @@ -122,7 +122,7 @@

We can define a Euclidean lattice just by its dimension::

sage: IntegralLattice(3)

Check failure on line 125 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[3]>", line 1, in <module> IntegralLattice(Integer(3)) ~~~~~~~~~~~~~~~^^^^^^^^^^^^ File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
Lattice of degree 3 and rank 3 over Integer Ring
Standard basis
Standard scalar product
Expand All @@ -131,14 +131,14 @@
Here is an example of the `A_2` root lattice in Euclidean space::

sage: basis = Matrix([[1,-1,0], [0,1,-1]])
sage: A2 = IntegralLattice(3, basis)

Check failure on line 134 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[5]>", line 1, in <module> A2 = IntegralLattice(Integer(3), basis) File "sage/misc/lazy_import.pyx", line 420, in sage.misc.lazy_import.LazyImport.__call__ return self.get_object()(*args, **kwds) File "sage/misc/lazy_import.pyx", line 230, in sage.misc.lazy_import.LazyImport.get_object return self._get_object() File "sage/misc/lazy_import.pyx", line 258, in sage.misc.lazy_import.LazyImport._get_object self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 625, in <module> class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_basis_pid): ...<1146 lines>... return FreeQuadraticModule_integer_symmetric(ambient=ambient, basis=self.basis(), inner_product_matrix=inner_product_matrix) File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/modules/free_quadratic_module_integer_symmetric.py", line 646, in FreeQuadraticModule_integer_symmetric class Element(FreeQuadraticModule_submodule_with_basis_pid.Element): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: type object 'FreeQuadraticModule_submodule_with_basis_pid' has no attribute 'Element'
sage: A2

Check failure on line 135 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[6]>", line 1, in <module> A2 NameError: name 'A2' is not defined
Lattice of degree 3 and rank 2 over Integer Ring
Basis matrix:
[ 1 -1 0]
[ 0 1 -1]
Standard scalar product
sage: A2.gram_matrix()

Check failure on line 141 in src/sage/modules/free_quadratic_module_integer_symmetric.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.13, new)

Failed example:

Failed example:: Exception raised: Traceback (most recent call last): File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 724, in _run self.compile_and_execute(example, compiler, test.globs) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/share/miniconda/envs/sage-dev/lib/python3.13/site-packages/sage/doctest/forker.py", line 1149, in compile_and_execute exec(compiled, globs) ~~~~^^^^^^^^^^^^^^^^^ File "<doctest sage.modules.free_quadratic_module_integer_symmetric.IntegralLattice[7]>", line 1, in <module> A2.gram_matrix() ^^ NameError: name 'A2' is not defined
[ 2 -1]
[-1 2]

Expand Down Expand Up @@ -643,6 +643,65 @@
[0 1]
[1 0]
"""
class Element(FreeQuadraticModule_submodule_with_basis_pid.Element):
r"""
An element of an integral lattice (i.e. a vector in a
:class:`FreeQuadraticModule_integer_symmetric`).
"""

def norm(self, p=2):
r"""
Return the `p`-norm of ``self``.

For `p = 2`, the norm is computed using the inner product matrix
of the parent lattice, so that ``norm()^2 == inner_product(self,
self)`` consistently (see :issue:`38543`).

For all other values of `p`, the standard `\ell^p` norm is used.

INPUT:

- ``p`` -- (default: 2) the norm parameter, as in
:meth:`~sage.modules.free_module_element.FreeModuleElement.norm`

EXAMPLES:

The 2-norm of a lattice vector respects the lattice inner product
matrix, so ``norm()^2 == inner_product(v, v)``::

sage: L = IntegralLattice(matrix([[1000, 0], [0, 1]]))
sage: v = L.0
sage: v.inner_product(v)
1000
sage: v.norm()^2
1000
sage: v.norm()^2 == v.inner_product(v)
True

The standard `\ell^1` norm is still the sum of absolute values::

sage: L = IntegralLattice(matrix([[2, 0], [0, 3]]))
sage: v = L([1, 2])
sage: v.norm(1)
3

TESTS:

Regression test for :issue:`38543`: before the fix, ``norm()^2``
used the plain Euclidean norm and disagreed with
``inner_product(v, v)``::

sage: L = IntegralLattice(matrix([[1000, 0], [0, 1]]))
sage: v = L.0
sage: v.norm()^2 == v.inner_product(v)
True
sage: v.norm()^2
1000
"""
if p == 2:
return self.inner_product(self).sqrt()
return super().norm(p)

def __init__(self, ambient, basis, inner_product_matrix,
check=True, already_echelonized=False):
r"""
Expand Down
Loading