@@ -4148,10 +4148,15 @@ cdef class FreeModuleElement(Vector): # abstract base class
4148
4148
4149
4149
nintegrate=nintegral
4150
4150
4151
- def concatenate(self, other):
4151
+ def concatenate(self, other, *, ring=None ):
4152
4152
r"""
4153
- Return the result of concatenating this vector with another
4154
- vector over the same ring.
4153
+ Return the result of concatenating this vector with a sequence
4154
+ of elements given by another iterable.
4155
+
4156
+ If the optional keyword argument ``ring`` is passed, this method
4157
+ will return a vector over the specified ring (or fail). If no
4158
+ base ring is given, the base ring is determined automatically by
4159
+ the :func:`vector` constructor.
4155
4160
4156
4161
EXAMPLES::
4157
4162
@@ -4166,26 +4171,63 @@ cdef class FreeModuleElement(Vector): # abstract base class
4166
4171
sage: v.concatenate(w).parent()
4167
4172
Ambient free module of rank 5 over the principal ideal domain Integer Ring
4168
4173
4169
- The method fails when the inputs aren' t both vectors, or the vectors
4170
- aren' t defined over the same ring::
4174
+ Forcing a base ring is possible using the ``ring`` argument::
4171
4175
4172
- sage: w2 = polygen(QQ)^ 4 + 5
4176
+ sage: v.concatenate(w, ring = QQ)
4177
+ (1 , 2 , 3 , 4 , 5 )
4178
+ sage: v.concatenate(w, ring = QQ).parent()
4179
+ Vector space of dimension 5 over Rational Field
4180
+
4181
+ ::
4182
+
4183
+ sage: v.concatenate(w, ring = Zmod(3 ))
4184
+ (1 , 2 , 0 , 1 , 2 )
4185
+
4186
+ The method accepts arbitrary iterables of elements which can
4187
+ be coerced to a common base ring::
4188
+
4189
+ sage: v.concatenate(range (4 ,8 ))
4190
+ (1 , 2 , 3 , 4 , 5 , 6 , 7 )
4191
+ sage: v.concatenate(range (4 ,8 )).parent()
4192
+ Ambient free module of rank 7 over the principal ideal domain Integer Ring
4193
+
4194
+ ::
4195
+
4196
+ sage: w2 = [4 , QQbar(- 5 ).sqrt()]
4173
4197
sage: v.concatenate(w2)
4174
- Traceback (most recent call last):
4175
- ...
4176
- TypeError : can only concatenate two vectors
4177
- sage: w2 = vector(QQ, [ 4 , 5 ] )
4198
+ ( 1 , 2 , 3 , 4 , 2.236 ... * I)
4199
+ sage: v.concatenate(w2).parent()
4200
+ Vector space of dimension 5 over Algebraic Field
4201
+ sage: w2 = vector(w2 )
4178
4202
sage: v.concatenate(w2)
4179
- Traceback (most recent call last):
4180
- ...
4181
- ValueError : can only concatenate vectors over the same base ring
4182
- """
4183
- if not isinstance(other, FreeModuleElement):
4184
- raise TypeError('can only concatenate two vectors')
4185
- R = self.parent().base_ring()
4186
- if other.parent().base_ring() != R:
4187
- raise ValueError('can only concatenate vectors over the same base ring')
4188
- return vector(R, list(self) + list(other))
4203
+ (1 , 2 , 3 , 4 , 2.236 ...* I)
4204
+ sage: v.concatenate(w2).parent()
4205
+ Vector space of dimension 5 over Algebraic Field
4206
+
4207
+ ::
4208
+
4209
+ sage: w2 = polygen(QQ)^ 4 + 5
4210
+ sage: v.concatenate(w2)
4211
+ (1 , 2 , 3 , 5 , 0 , 0 , 0 , 1 )
4212
+ sage: v.concatenate(w2).parent()
4213
+ Vector space of dimension 8 over Rational Field
4214
+ sage: v.concatenate(w2, ring = ZZ)
4215
+ (1 , 2 , 3 , 5 , 0 , 0 , 0 , 1 )
4216
+ sage: v.concatenate(w2, ring = ZZ).parent()
4217
+ Ambient free module of rank 8 over the principal ideal domain Integer Ring
4218
+
4219
+ ::
4220
+
4221
+ sage: v.concatenate(GF(9 ).gens())
4222
+ (1 , 2 , 0 , z2)
4223
+ sage: v.concatenate(GF(9 ).gens()).parent()
4224
+ Vector space of dimension 4 over Finite Field in z2 of size 3 ^ 2
4225
+ """
4226
+ from itertools import chain
4227
+ coeffs = chain(self, other)
4228
+ if ring is not None:
4229
+ return vector(ring, coeffs)
4230
+ return vector(coeffs)
4189
4231
4190
4232
#############################################
4191
4233
# Generic dense element
0 commit comments