Skip to content
Open
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
90 changes: 85 additions & 5 deletions src/sage/algebras/lie_algebras/lie_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,25 +553,86 @@ def _element_constructor_(self, x):
sage: L = lie_algebras.pwitt(GF(5), 5)
sage: L(0)
0

Vectors coming from the underlying module coerce back in::

sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x': 1}})
sage: v = (x + 2*y).to_vector()
sage: L(v)
x + 2*y
sage: L(v.change_ring(ZZ))
x + 2*y
"""
if isinstance(x, list) and len(x) == 2:
return self(x[0])._bracket_(self(x[1]))

if x == 0:
return self.zero()

try:
if x in self.module():
return self.from_vector(x)
except AttributeError:
pass
coerced = self._coerce_from_module_vector(x)
if coerced is not None:
return coerced

if x in self.base_ring():
# We have already handled the case when x == 0
raise ValueError("can only convert the scalar 0 into a Lie algebra element")

return self.element_class(self, x)

def _coerce_from_module_vector(self, x):
"""
Try to coerce ``x`` coming from ``self.module()``.

INPUT:

- ``x`` -- an element to be coerced

OUTPUT:

- an element of ``self`` if coercion is possible, ``None`` otherwise
"""
from_vector = getattr(self, "from_vector", None)
if from_vector is None:
return None

try:
x_parent = x.parent()
except AttributeError:
return None

vector_modules = []
for attr in ("_M", "_module"):
mod = getattr(self, attr, None)
if mod is None or mod is NotImplemented or callable(mod):
continue
vector_modules.append(mod)

module_method = getattr(self, "module", None)
if callable(module_method):
try:
mod = module_method()
except (AttributeError, TypeError, NotImplementedError):
mod = None
if mod is not None:
vector_modules.append(mod)

seen_ids = set()
for mod in vector_modules:
key = id(mod)
seen_ids.add(key)
if x_parent is mod:
return from_vector(x)
has_cm = getattr(mod, "has_coerce_map_from", None)
if (x_parent is not None and callable(has_cm)
and has_cm(x_parent)):
try:
vec = mod(x)
except (TypeError, ValueError):
continue
return from_vector(vec)

return None

def __getitem__(self, x):
"""
If ``x`` is a pair `(a, b)`, return the Lie bracket `[a, b]
Expand Down Expand Up @@ -1240,9 +1301,28 @@ def _element_constructor_(self, x):
-[1, 3, 2] + [3, 2, 1]
sage: L(2)
2*[1, 2, 3]

TESTS:

Test that constructing elements from vectors works correctly::

sage: gl = lie_algebras.gl(QQ, 2)
sage: v = gl.an_element().to_vector()
sage: gl(v) == gl.an_element()
True

Test that morphisms can be constructed::

sage: gl = lie_algebras.gl(QQ, 2)
sage: phi = gl.morphism({e: e for e in gl.gens()})
sage: all(phi(e) == e for e in gl.gens())
True
"""
if isinstance(x, list) and len(x) == 2:
return self(x[0])._bracket_(self(x[1]))
coerced = self._coerce_from_module_vector(x)
if coerced is not None:
return coerced
return self.element_class(self, self._assoc(x))

def associative_algebra(self):
Expand Down
Loading