Skip to content
This repository was archived by the owner on Feb 1, 2023. It is now read-only.

Commit 1b1ee7f

Browse files
author
Michael Jung
committed
Zero/One check added
1 parent 371a255 commit 1b1ee7f

15 files changed

+228
-70
lines changed

src/sage/manifolds/differentiable/automorphismfield.py

Lines changed: 153 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ class AutomorphismField(TensorField):
139139
True
140140
141141
"""
142-
def __init__(self, vector_field_module, name=None, latex_name=None,
143-
is_identity=False):
142+
def __init__(self, vector_field_module, name=None, latex_name=None):
144143
r"""
145144
Construct a field of tangent-space automorphisms on a
146145
non-parallelizable manifold.
@@ -168,7 +167,7 @@ def __init__(self, vector_field_module, name=None, latex_name=None,
168167
169168
Construction of the identity field::
170169
171-
sage: b = GL.element_class(XM, is_identity=True); b
170+
sage: b = GL.one(); b
172171
Field of tangent-space identity maps on the 2-dimensional
173172
differentiable manifold M
174173
sage: TestSuite(b).run(skip='_test_pickling')
@@ -186,24 +185,11 @@ def __init__(self, vector_field_module, name=None, latex_name=None,
186185
Fix ``_test_pickling`` (in the superclass :class:`TensorField`).
187186
188187
"""
189-
if is_identity:
190-
if name is None:
191-
name = 'Id'
192-
if latex_name is None and name == 'Id':
193-
latex_name = r'\mathrm{Id}'
194188
TensorField.__init__(self, vector_field_module, (1,1), name=name,
195189
latex_name=latex_name,
196190
parent=vector_field_module.general_linear_group())
197-
self._is_identity = is_identity
191+
self._is_identity = False # a priori
198192
self._init_derived() # initialization of derived quantities
199-
# Specific initializations for the field of identity maps:
200-
if self._is_identity:
201-
self._inverse = self
202-
for dom in self._domain._subsets:
203-
if dom.is_manifestly_parallelizable():
204-
fmodule = dom.vector_field_module()
205-
self._restrictions[dom] = fmodule.identity_map(name=name,
206-
latex_name=latex_name)
207193

208194
def _repr_(self):
209195
r"""
@@ -261,6 +247,152 @@ def _del_derived(self):
261247
# then deletes the inverse automorphism:
262248
self._inverse = None
263249

250+
def set_comp(self, basis=None, **kwargs):
251+
r"""
252+
Return the components of ``self`` w.r.t. a given module basis for
253+
assignment.
254+
255+
The components with respect to other bases are deleted, in order to
256+
avoid any inconsistency. To keep them, use the method :meth:`add_comp`
257+
instead.
258+
259+
INPUT:
260+
261+
- ``basis`` -- (default: ``None``) basis in which the components are
262+
defined; if none is provided, the components are assumed to refer to
263+
the module's default basis
264+
265+
OUTPUT:
266+
267+
- components in the given basis, as an instance of the
268+
class :class:`~sage.tensor.modules.comp.Components`; if such
269+
components did not exist previously, they are created.
270+
271+
EXAMPLES::
272+
273+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
274+
sage: U = M.open_subset('U') # complement of the North pole
275+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
276+
sage: V = M.open_subset('V') # complement of the South pole
277+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
278+
sage: M.declare_union(U,V) # S^2 is the union of U and V
279+
sage: e_uv = c_uv.frame()
280+
sage: a= M.automorphism_field(name='a')
281+
sage: a.set_comp(e_uv)
282+
2-indices components w.r.t. Coordinate frame (V, (d/du,d/dv))
283+
sage: a.set_comp(e_uv)[0,0] = u+v
284+
sage: a.set_comp(e_uv)[1,1] = u+v
285+
sage: a.display(e_uv)
286+
a = (u + v) d/du*du + (u + v) d/dv*dv
287+
288+
Setting the components in a new frame::
289+
290+
sage: e = V.vector_frame('e')
291+
sage: a.set_comp(e)
292+
2-indices components w.r.t. Vector frame (V, (e_0,e_1))
293+
sage: a.set_comp(e)[0,1] = u*v
294+
sage: a.set_comp(e)[1,0] = u*v
295+
sage: a.display(e)
296+
a = u*v e_0*e^1 + u*v e_1*e^0
297+
298+
Since the frames ``e`` and ``e_uv`` are defined on the same domain, the
299+
components w.r.t. ``e_uv`` have been erased::
300+
301+
sage: a.display(c_uv.frame())
302+
Traceback (most recent call last):
303+
...
304+
ValueError: no basis could be found for computing the components
305+
in the Coordinate frame (V, (d/du,d/dv))
306+
307+
Since the identity map is a special element, its components cannot be
308+
changed::
309+
310+
sage: id = M.tangent_identity_field()
311+
sage: id.add_comp(e)[0,1] = u*v
312+
Traceback (most recent call last):
313+
...
314+
AssertionError: the components of the identity map cannot be changed
315+
316+
"""
317+
if self._is_identity:
318+
raise AssertionError("the components of the identity map cannot be "
319+
"changed")
320+
return TensorField.set_comp(self, basis=basis, check_elements=False)
321+
322+
def add_comp(self, basis=None, **kwargs):
323+
r"""
324+
325+
Return the components of ``self`` w.r.t. a given module basis for
326+
assignment, keeping the components w.r.t. other bases.
327+
328+
To delete the components w.r.t. other bases, use the method
329+
:meth:`set_comp` instead.
330+
331+
INPUT:
332+
333+
- ``basis`` -- (default: ``None``) basis in which the components are
334+
defined; if none is provided, the components are assumed to refer to
335+
the module's default basis
336+
337+
.. WARNING::
338+
339+
If the automorphism field has already components in other bases, it
340+
is the user's responsibility to make sure that the components
341+
to be added are consistent with them.
342+
343+
OUTPUT:
344+
345+
- components in the given basis, as an instance of the
346+
class :class:`~sage.tensor.modules.comp.Components`;
347+
if such components did not exist previously, they are created
348+
349+
EXAMPLES::
350+
351+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
352+
sage: U = M.open_subset('U') # complement of the North pole
353+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
354+
sage: V = M.open_subset('V') # complement of the South pole
355+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
356+
sage: M.declare_union(U,V) # S^2 is the union of U and V
357+
sage: e_uv = c_uv.frame()
358+
sage: a= M.automorphism_field(name='a')
359+
sage: a.add_comp(e_uv)
360+
2-indices components w.r.t. Coordinate frame (V, (d/du,d/dv))
361+
sage: a.add_comp(e_uv)[0,0] = u+v
362+
sage: a.add_comp(e_uv)[1,1] = u+v
363+
sage: a.display(e_uv)
364+
a = (u + v) d/du*du + (u + v) d/dv*dv
365+
366+
Setting the components in a new frame::
367+
368+
sage: e = V.vector_frame('e')
369+
sage: a.add_comp(e)
370+
2-indices components w.r.t. Vector frame (V, (e_0,e_1))
371+
sage: a.add_comp(e)[0,1] = u*v
372+
sage: a.add_comp(e)[1,0] = u*v
373+
sage: a.display(e)
374+
a = u*v e_0*e^1 + u*v e_1*e^0
375+
376+
The components with respect to ``e_uv`` are kept::
377+
378+
sage: a.display(e_uv)
379+
a = (u + v) d/du*du + (u + v) d/dv*dv
380+
381+
Since the identity map is a special element, its components cannot be
382+
changed::
383+
384+
sage: id = M.tangent_identity_field()
385+
sage: id.add_comp(e)[0,1] = u*v
386+
Traceback (most recent call last):
387+
...
388+
AssertionError: the components of the identity map cannot be changed
389+
390+
"""
391+
if self._is_identity:
392+
raise AssertionError("the components of the identity map cannot be "
393+
"changed")
394+
return TensorField.add_comp(self, basis=basis, check_elements=False)
395+
264396
def _new_instance(self):
265397
r"""
266398
Create an instance of the same class as ``self`` on the same
@@ -789,8 +921,6 @@ class AutomorphismFieldParal(FreeModuleAutomorphism, TensorFieldParal):
789921
- ``name`` -- (default: ``None``) name given to the field
790922
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field;
791923
if none is provided, the LaTeX symbol is set to ``name``
792-
- ``is_identity`` -- (default: ``False``) determines whether the
793-
constructed object is a field of identity automorphisms
794924
795925
EXAMPLES:
796926
@@ -834,8 +964,7 @@ class AutomorphismFieldParal(FreeModuleAutomorphism, TensorFieldParal):
834964
True
835965
836966
"""
837-
def __init__(self, vector_field_module, name=None, latex_name=None,
838-
is_identity=False):
967+
def __init__(self, vector_field_module, name=None, latex_name=None):
839968
r"""
840969
Construct a field of tangent-space automorphisms.
841970
@@ -861,7 +990,7 @@ def __init__(self, vector_field_module, name=None, latex_name=None,
861990
862991
Construction of the field of identity maps::
863992
864-
sage: b = GL.element_class(XM, is_identity=True); b
993+
sage: b = GL.one(); b
865994
Field of tangent-space identity maps on the 2-dimensional
866995
differentiable manifold M
867996
sage: b[:]
@@ -871,12 +1000,12 @@ def __init__(self, vector_field_module, name=None, latex_name=None,
8711000
8721001
"""
8731002
FreeModuleAutomorphism.__init__(self, vector_field_module,
874-
name=name, latex_name=latex_name,
875-
is_identity=is_identity)
1003+
name=name, latex_name=latex_name)
8761004
# TensorFieldParal attributes:
8771005
self._vmodule = vector_field_module
8781006
self._domain = vector_field_module._domain
8791007
self._ambient_domain = vector_field_module._ambient_domain
1008+
self._is_identity = False # a priori
8801009
# Initialization of derived quantities:
8811010
TensorFieldParal._init_derived(self)
8821011

src/sage/manifolds/differentiable/automorphismfield_group.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,16 @@ def one(self):
300300
[0 1]
301301
302302
"""
303-
return self.element_class(self._vmodule, is_identity=True)
303+
# Specific initializations for the field of identity maps:
304+
resu = self._element_constructor_(name='Id', latex_name=r'\mathrm{Id}')
305+
resu._inverse = resu
306+
for dom in resu._domain._subsets:
307+
if dom.is_manifestly_parallelizable():
308+
fmodule = dom.vector_field_module()
309+
resu._restrictions[dom] = fmodule.identity_map(name='Id',
310+
latex_name=r'\mathrm{Id}')
311+
resu._is_identity = True
312+
return resu
304313

305314
#### End of monoid methods ####
306315

src/sage/manifolds/differentiable/diff_form_module.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ def zero(self):
446446
zero = self._element_constructor_(name='zero', latex_name='0')
447447
for frame in self._domain._frames:
448448
if self._dest_map.restrict(frame._domain) == frame._dest_map:
449-
zero.add_comp(frame)
449+
zero.add_comp(frame, check_elements=False)
450450
# (since new components are initialized to zero)
451451
zero._is_zero = True # This element is certainly zero
452452
return zero

src/sage/manifolds/differentiable/multivector_module.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ def zero(self):
395395
zero = self._element_constructor_(name='zero', latex_name='0')
396396
for frame in self._domain._frames:
397397
if self._dest_map.restrict(frame._domain) == frame._dest_map:
398-
zero.add_comp(frame)
398+
zero.add_comp(frame, check_elements=False)
399399
# (since new components are initialized to zero)
400400
return zero
401401

src/sage/manifolds/differentiable/tensorfield.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ def restrict(self, subdomain, dest_map=None):
10771077

10781078
return self._restrictions[subdomain]
10791079

1080-
def set_comp(self, basis=None):
1080+
def set_comp(self, basis=None, **kwargs):
10811081
r"""
10821082
Return the components of ``self`` in a given vector frame
10831083
for assignment.
@@ -1132,15 +1132,28 @@ def set_comp(self, basis=None):
11321132
ValueError: no basis could be found for computing the components
11331133
in the Coordinate frame (V, (d/du,d/dv))
11341134
1135+
Since zero is a special element, its components cannot be changed::
1136+
1137+
sage: z = M.tensor_field_module((1, 1)).zero()
1138+
sage: z.set_comp(e)[0,1] = u*v
1139+
Traceback (most recent call last):
1140+
...
1141+
AssertionError: the components of the zero element cannot be changed
1142+
11351143
"""
1144+
check_elements = kwargs.pop('check_elements', True)
1145+
if check_elements:
1146+
if self is self.parent().zero():
1147+
raise AssertionError("the components of the zero element "
1148+
"cannot be changed")
1149+
self._is_zero = False # a priori
11361150
if basis is None:
11371151
basis = self._domain._def_frame
11381152
self._del_derived() # deletes the derived quantities
1139-
self._is_zero = False # a priori
11401153
rst = self.restrict(basis._domain, dest_map=basis._dest_map)
1141-
return rst.set_comp(basis)
1154+
return rst.set_comp(basis, **kwargs)
11421155

1143-
def add_comp(self, basis=None):
1156+
def add_comp(self, basis=None, **kwargs):
11441157
r"""
11451158
Return the components of ``self`` in a given vector frame
11461159
for assignment.
@@ -1191,13 +1204,26 @@ def add_comp(self, basis=None):
11911204
sage: t.display(e_uv)
11921205
t = (u + v) d/dv*du*dv
11931206
1207+
Since zero is a special element, its components cannot be changed::
1208+
1209+
sage: z = M.tensor_field_module((1, 1)).zero()
1210+
sage: z.add_comp(e)[0,1] = u*v
1211+
Traceback (most recent call last):
1212+
...
1213+
AssertionError: the components of the zero element cannot be changed
1214+
11941215
"""
1216+
check_elements = kwargs.pop('check_elements', True)
1217+
if check_elements:
1218+
if self is self.parent().zero():
1219+
raise AssertionError("the components of the zero element "
1220+
"cannot be changed")
1221+
self._is_zero = False # a priori
11951222
if basis is None:
11961223
basis = self._domain._def_frame
11971224
self._del_derived() # deletes the derived quantities
1198-
self._is_zero = False # a priori
11991225
rst = self.restrict(basis._domain, dest_map=basis._dest_map)
1200-
return rst.add_comp(basis)
1226+
return rst.add_comp(basis, **kwargs)
12011227

12021228
def add_comp_by_continuation(self, frame, subdomain, chart=None):
12031229
r"""
@@ -1271,10 +1297,10 @@ def add_comp_by_continuation(self, frame, subdomain, chart=None):
12711297
sframe = frame.restrict(subdomain)
12721298
schart = chart.restrict(subdomain)
12731299
scomp = self.comp(sframe)
1274-
resu = self.add_comp(frame) # _del_derived is performed here
1300+
resu = self.add_comp(frame, check_elements=False) # _del_derived is
1301+
# performed here
12751302
for ind in resu.non_redundant_index_generator():
12761303
resu[[ind]] = dom.scalar_field({chart: scomp[[ind]].expr(schart)})
1277-
self._is_zero = False # a priori
12781304

12791305
def add_expr_from_subdomain(self, frame, subdomain):
12801306
r"""
@@ -1366,14 +1392,13 @@ def add_expr_from_subdomain(self, frame, subdomain):
13661392
if frame not in self.restrict(frame.domain())._components:
13671393
raise ValueError("the tensor doesn't have an expression in "
13681394
"the frame"+frame._repr_())
1369-
comp = self.comp(frame)
1395+
comp = self.add_comp(frame, check_elements=False)
13701396
scomp = self.restrict(subdomain).comp(frame.restrict(subdomain))
13711397
for ind in comp.non_redundant_index_generator():
13721398
comp[[ind]]._express.update(scomp[[ind]]._express)
13731399

13741400
rst = self._restrictions.copy()
13751401
self._del_derived() # delete restrictions
1376-
self._is_zero = False # a priori
13771402
self._restrictions = rst
13781403

13791404
def comp(self, basis=None, from_basis=None):

src/sage/manifolds/differentiable/tensorfield_module.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ def zero(self):
575575
resu = self._element_constructor_(name='zero', latex_name='0')
576576
for frame in self._domain._frames:
577577
if self._dest_map.restrict(frame._domain) == frame._dest_map:
578-
resu.add_comp(frame)
578+
resu.add_comp(frame, check_elements=False)
579579
# (since new components are initialized to zero)
580580
resu._is_zero = True # This element is certainly zero
581581
return resu

0 commit comments

Comments
 (0)