Skip to content

Commit

Permalink
gh-36971: add helper method to concatenate vectors
Browse files Browse the repository at this point in the history
    
Writing `vector(R, list(v) + list(w))` is a common way to concatenate
two vectors `v` and `w` over some ring `R`.

In this patch we introduce a simple helper method which allows writing
`v.concatenate(w)` instead.
    
URL: #36971
Reported by: Lorenz Panny
Reviewer(s): grhkm21, Ruchit Jagodara
  • Loading branch information
Release Manager committed Mar 21, 2024
2 parents 3abc045 + 4d1f385 commit 3ea5fa9
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/sage/modules/free_module_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -4148,6 +4148,87 @@ cdef class FreeModuleElement(Vector): # abstract base class
nintegrate=nintegral
def concatenate(self, other, *, ring=None):
r"""
Return the result of concatenating this vector with a sequence
of elements given by another iterable.

If the optional keyword argument ``ring`` is passed, this method
will return a vector over the specified ring (or fail). If no
base ring is given, the base ring is determined automatically by
the :func:`vector` constructor.

EXAMPLES::

sage: v = vector([1, 2, 3])
sage: w = vector([4, 5])
sage: v.concatenate(w)
(1, 2, 3, 4, 5)
sage: v.parent()
Ambient free module of rank 3 over the principal ideal domain Integer Ring
sage: w.parent()
Ambient free module of rank 2 over the principal ideal domain Integer Ring
sage: v.concatenate(w).parent()
Ambient free module of rank 5 over the principal ideal domain Integer Ring

Forcing a base ring is possible using the ``ring`` argument::

sage: v.concatenate(w, ring=QQ)
(1, 2, 3, 4, 5)
sage: v.concatenate(w, ring=QQ).parent()
Vector space of dimension 5 over Rational Field

::

sage: v.concatenate(w, ring=Zmod(3))
(1, 2, 0, 1, 2)

The method accepts arbitrary iterables of elements which can
be coerced to a common base ring::

sage: v.concatenate(range(4,8))
(1, 2, 3, 4, 5, 6, 7)
sage: v.concatenate(range(4,8)).parent()
Ambient free module of rank 7 over the principal ideal domain Integer Ring

::

sage: w2 = [4, QQbar(-5).sqrt()]
sage: v.concatenate(w2)
(1, 2, 3, 4, 2.236...*I)
sage: v.concatenate(w2).parent()
Vector space of dimension 5 over Algebraic Field
sage: w2 = vector(w2)
sage: v.concatenate(w2)
(1, 2, 3, 4, 2.236...*I)
sage: v.concatenate(w2).parent()
Vector space of dimension 5 over Algebraic Field

::

sage: w2 = polygen(QQ)^4 + 5
sage: v.concatenate(w2)
(1, 2, 3, 5, 0, 0, 0, 1)
sage: v.concatenate(w2).parent()
Vector space of dimension 8 over Rational Field
sage: v.concatenate(w2, ring=ZZ)
(1, 2, 3, 5, 0, 0, 0, 1)
sage: v.concatenate(w2, ring=ZZ).parent()
Ambient free module of rank 8 over the principal ideal domain Integer Ring

::

sage: v.concatenate(GF(9).gens())
(1, 2, 0, z2)
sage: v.concatenate(GF(9).gens()).parent()
Vector space of dimension 4 over Finite Field in z2 of size 3^2
"""
from itertools import chain
coeffs = chain(self, other)
if ring is not None:
return vector(ring, coeffs)
return vector(coeffs)
#############################################
# Generic dense element
#############################################
Expand Down

0 comments on commit 3ea5fa9

Please sign in to comment.