Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge branch 't/30181/immutable_elements_of_freemoduletensor' into t/…
Browse files Browse the repository at this point in the history
…30310/immutability_of_chart_functions
  • Loading branch information
Michael Jung committed Aug 7, 2020
2 parents 83caa4b + a2ee8be commit 8600c2d
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 61 deletions.
1 change: 0 additions & 1 deletion src/sage/modules/free_module_element.pxd
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from sage.structure.element cimport Vector

cdef class FreeModuleElement(Vector):
cdef bint _is_mutable
cdef int set_unsafe(self, Py_ssize_t i, value) except -1
cdef get_unsafe(self, Py_ssize_t i)
cpdef int hamming_weight(self)
Expand Down
47 changes: 0 additions & 47 deletions src/sage/modules/free_module_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1485,53 +1485,6 @@ cdef class FreeModuleElement(Vector): # abstract base class
"""
return self.parent()([ a.subs(in_dict, **kwds) for a in self.list() ])

def set_immutable(self):
"""
Make this vector immutable. This operation can't be undone.
EXAMPLES::
sage: v = vector([1..5]); v
(1, 2, 3, 4, 5)
sage: v[1] = 10
sage: v.set_immutable()
sage: v[1] = 10
Traceback (most recent call last):
...
ValueError: vector is immutable; please change a copy instead (use copy())
"""
self._is_mutable = 0

def is_mutable(self):
"""
Return True if this vector is mutable, i.e., the entries can be
changed.
EXAMPLES::
sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable()
True
sage: v.set_immutable()
sage: v.is_mutable()
False
"""
return self._is_mutable

def is_immutable(self):
"""
Return True if this vector is immutable, i.e., the entries cannot
be changed.
EXAMPLES::
sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable()
False
sage: v.set_immutable()
sage: v.is_immutable()
True
"""
return not self._is_mutable

def change_ring(self, R):
"""
Change the base ring of this vector.
Expand Down
7 changes: 6 additions & 1 deletion src/sage/structure/element.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ cdef class ModuleElement(Element):
# self._lmul_(x) is self * x
cpdef _rmul_(self, Element left)

cdef class ModuleElementWithMutability(ModuleElement):
cdef bint _is_mutable
cpdef bint is_immutable(self)
cpdef bint is_mutable(self)

cdef class MonoidElement(Element):
cpdef _pow_int(self, n)

Expand Down Expand Up @@ -234,7 +239,7 @@ cdef class InfinityElement(RingElement):
pass


cdef class Vector(ModuleElement):
cdef class Vector(ModuleElementWithMutability):
cdef Py_ssize_t _degree

# Return the dot product using the simple metric
Expand Down
65 changes: 64 additions & 1 deletion src/sage/structure/element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,69 @@ cdef class ModuleElement(Element):
"""
raise NotImplementedError

cdef class ModuleElementWithMutability(ModuleElement):
"""
Generic element of a module with mutability.
"""

def __init__(self, parent):
"""
EXAMPLES::
sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3)
sage: type(v)
<type 'sage.modules.free_module_element.FreeModuleElement'>
"""
self._parent = parent
self._is_mutable = 1

def set_immutable(self):
"""
Make this vector immutable. This operation can't be undone.
EXAMPLES::
sage: v = vector([1..5]); v
(1, 2, 3, 4, 5)
sage: v[1] = 10
sage: v.set_immutable()
sage: v[1] = 10
Traceback (most recent call last):
...
ValueError: vector is immutable; please change a copy instead (use copy())
"""
self._is_mutable = 0

cpdef bint is_mutable(self):
"""
Return True if this vector is mutable, i.e., the entries can be
changed.
EXAMPLES::
sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable()
True
sage: v.set_immutable()
sage: v.is_mutable()
False
"""
return self._is_mutable

cpdef bint is_immutable(self):
"""
Return True if this vector is immutable, i.e., the entries cannot
be changed.
EXAMPLES::
sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable()
False
sage: v.set_immutable()
sage: v.is_immutable()
True
"""
return not self._is_mutable

########################################################################
# Monoid
########################################################################
Expand Down Expand Up @@ -3099,7 +3162,7 @@ cdef class CommutativeRingElement(RingElement):

##############################################

cdef class Vector(ModuleElement):
cdef class Vector(ModuleElementWithMutability):
cdef bint is_sparse_c(self):
raise NotImplementedError

Expand Down
2 changes: 2 additions & 0 deletions src/sage/tensor/modules/ext_pow_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ def zero(self):
resu._add_comp_unsafe(basis)
# (since new components are initialized to zero)
resu._is_zero = True # This element is certainly zero
resu.set_immutable()
return resu

def _repr_(self):
Expand Down Expand Up @@ -804,6 +805,7 @@ def zero(self):
resu._components[basis] = resu._new_comp(basis)
# (since new components are initialized to zero)
resu._is_zero = True # This element is certainly zero
resu.set_immutable()
return resu

def _repr_(self):
Expand Down
1 change: 1 addition & 0 deletions src/sage/tensor/modules/finite_rank_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,7 @@ def zero(self):
resu._add_comp_unsafe(basis)
# (since new components are initialized to zero)
resu._is_zero = True # This element is certainly zero
resu.set_immutable()
return resu

def dual(self):
Expand Down
1 change: 1 addition & 0 deletions src/sage/tensor/modules/free_module_linear_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ def one(self):
start_index=fmodule._sindex,
output_formatter=fmodule._output_formatter)
resu._is_identity = True
resu.set_immutable()
return resu

#### End of monoid methods ####
Expand Down
22 changes: 11 additions & 11 deletions src/sage/tensor/modules/free_module_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class being:
from __future__ import absolute_import

from sage.rings.integer import Integer
from sage.structure.element import ModuleElement
from sage.structure.element import ModuleElementWithMutability
from sage.tensor.modules.comp import (Components, CompWithSym, CompFullySym,
CompFullyAntiSym)
from sage.tensor.modules.tensor_with_indices import TensorWithIndices
Expand All @@ -206,7 +206,7 @@ class being:
# TODO: remove the import of Chart after _preparse_display has been redefined
# in tensor fields

class FreeModuleTensor(ModuleElement):
class FreeModuleTensor(ModuleElementWithMutability):
r"""
Tensor over a free module of finite rank over a commutative ring.
Expand Down Expand Up @@ -281,7 +281,7 @@ def __init__(self, fmodule, tensor_type, name=None, latex_name=None,
"""
if parent is None:
parent = fmodule.tensor_module(*tensor_type)
ModuleElement.__init__(self, parent)
super().__init__(parent)
self._fmodule = fmodule
self._tensor_type = tuple(tensor_type)
self._tensor_rank = self._tensor_type[0] + self._tensor_type[1]
Expand Down Expand Up @@ -1319,17 +1319,17 @@ class :class:`~sage.tensor.modules.comp.Components`; if such
[Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring,
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring]
Since zero is a special element, its components cannot be changed::
Since zero is an immutable element, its components cannot be changed::
sage: z = M.tensor_module(1, 1).zero()
sage: z.set_comp(e)[0,1] = 1
Traceback (most recent call last):
...
AssertionError: the components of the zero element cannot be changed
AssertionError: the components of an immutable element cannot be changed
"""
if self is self.parent().zero():
raise AssertionError("the components of the zero element "
if self.is_immutable():
raise AssertionError("the components of an immutable element "
"cannot be changed")
self._is_zero = False # a priori
return self._set_comp_unsafe(basis)
Expand Down Expand Up @@ -1456,17 +1456,17 @@ class :class:`~sage.tensor.modules.comp.Components`;
sage: t.display(e)
t = -3 e_0*e^1 + 2 e_1*e^2
Since zero is a special element, its components cannot be changed::
Since zero is an immutable element, its components cannot be changed::
sage: z = M.tensor_module(1, 1).zero()
sage: z.add_comp(e)[0,1] = 1
Traceback (most recent call last):
...
AssertionError: the components of the zero element cannot be changed
AssertionError: the components of an immutable element cannot be changed
"""
if self is self.parent().zero():
raise AssertionError("the components of the zero element "
if self.is_immutable():
raise AssertionError("the components of an immutable element "
"cannot be changed")
self._is_zero = False # a priori
return self._add_comp_unsafe(basis)
Expand Down
1 change: 1 addition & 0 deletions src/sage/tensor/modules/tensor_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ def zero(self):
resu._add_comp_unsafe(basis)
# (since new components are initialized to zero)
resu._is_zero = True # This element is certainly zero
resu.set_immutable()
return resu

def _an_element_(self):
Expand Down

0 comments on commit 8600c2d

Please sign in to comment.