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

Commit

Permalink
Add _basis_index_function as a method, fix some doctests, and fix som…
Browse files Browse the repository at this point in the history
…e type issues (tuple -> FrozenBitset)
  • Loading branch information
trevorkarn committed Jun 21, 2022
1 parent 5df9054 commit 0ca83ab
Showing 1 changed file with 55 additions and 16 deletions.
71 changes: 55 additions & 16 deletions src/sage/algebras/clifford_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from sage.misc.cachefunc import cached_method
from sage.structure.unique_representation import UniqueRepresentation
from sage.data_structures.bitset import FrozenBitset
from sage.data_structures.bitset import Bitset, FrozenBitset
from copy import copy

from sage.categories.algebras_with_basis import AlgebrasWithBasis
Expand Down Expand Up @@ -178,9 +178,9 @@ def list(self):
sage: Cl.<x,y,z> = CliffordAlgebra(Q)
sage: elt = 5*x + y
sage: elt.list()
[((0,), 5), ((1,), 1)]
[(1, 5), (01, 1)]
"""
return sorted(self._monomial_coefficients.items(), key=lambda m_c : (-len(m_c[0]), m_c[0]))
return sorted(self._monomial_coefficients.items(), key=lambda m_c : (-len(m_c[0]), m_c))

def support(self):
"""
Expand All @@ -195,7 +195,7 @@ def support(self):
sage: Cl.<x,y,z> = CliffordAlgebra(Q)
sage: elt = 5*x + y
sage: elt.support()
[(0,), (1,)]
[1, 01]
"""
return sorted(self._monomial_coefficients.keys(), key=lambda x: (-len(x), x))

Expand Down Expand Up @@ -552,13 +552,8 @@ def __init__(self, Q, names, category=None):
self._quadratic_form = Q
R = Q.base_ring()
category = AlgebrasWithBasis(R.category()).Super().Filtered().FiniteDimensional().or_subcategory(category)
format_style = f"0{Q.dim()}b"
from functools import partial
# use a slice to reverse string order because Bitset and format(x, 'b') use different conventions
def index_function(x):
return FrozenBitset(format(x, format_style)[::-1],
capacity=Q.dim())
indices = Family(range(2**Q.dim()), partial(index_function), lazy=True)
indices = Family(range(2**Q.dim()), partial(self._basis_index_function), lazy=True)
CombinatorialFreeModule.__init__(self, R, indices, category=category)
self._assign_names(names)

Expand Down Expand Up @@ -739,16 +734,58 @@ def _element_constructor_(self, x):
if x in self.free_module():
R = self.base_ring()
if x.parent().base_ring() is R:
return self.element_class(self, {(i,): c for i,c in x.items()})
return self.element_class(self, {(i,): R(c) for i,c in x.items() if R(c) != R.zero()})
return self.element_class(self, {FrozenBitset((i,)): c for i,c in x.items()})
# if the base ring is different, attempt to coerce it into R
return self.element_class(self, {FrozenBitset((i,)): R(c) for i,c in x.items() if R(c) != R.zero()})

if (isinstance(x, CliffordAlgebraElement)
and self.has_coerce_map_from(x.parent())):
R = self.base_ring()
return self.element_class(self, {i: R(c) for i,c in x if R(c) != R.zero()})

if isinstance(x, tuple):
R = self.base_ring()
return self.element_class(self, {FrozenBitset((i,)): R.one() for i in x})

return super(CliffordAlgebra, self)._element_constructor_(x)

def _basis_index_function(self, x):
"""
Given an integer indexing the basis, return the correct
bitset.
For backwards compatibility, tuples are also accepted.
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
sage: Cl = CliffordAlgebra(Q)
sage: Cl._basis_index_function(7)
111
sage: Cl._basis_index_function(5)
101
sage: Cl._basis_index_function(4)
001
sage: Cl._basis_index_function((0, 1, 2))
111
sage: Cl._basis_index_function((0, 2))
101
sage: Cl._basis_index_function((2,))
001
"""
Q = self._quadratic_form
format_style = f"0{Q.dim()}b"

# if the input is a tuple, assume that it has
# entries in {0, ..., 2**Q.dim()-1}
if isinstance(x, tuple):
return FrozenBitset(x, capacity = Q.dim())

# slice the output of format in order to make conventions
# of format and FrozenBitset agree.
return FrozenBitset(format(x, format_style)[::-1], capacity=Q.dim())

def gen(self, i):
"""
Return the ``i``-th standard generator of the algebra ``self``.
Expand All @@ -764,7 +801,7 @@ def gen(self, i):
sage: [Cl.gen(i) for i in range(3)]
[x, y, z]
"""
return self._from_dict({(i,): self.base_ring().one()}, remove_zeros=False)
return self._from_dict({FrozenBitset((i,)): self.base_ring().one()}, remove_zeros=False)

def algebra_generators(self):
"""
Expand Down Expand Up @@ -809,14 +846,16 @@ def ngens(self):
@cached_method
def one_basis(self):
"""
Return the basis index of the element `1`.
Return the basis index of the element ``1``. The element ``1``
is indexed by the emptyset, which is represented by the
:class:`sage.data_structures.bitset.Bitset` ``0``.
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
sage: Cl.<x,y,z> = CliffordAlgebra(Q)
sage: Cl.one_basis()
()
0
"""
return FrozenBitset('0')

Expand Down Expand Up @@ -1090,7 +1129,7 @@ def lift_module_morphism(self, m, names=None):
Cl = CliffordAlgebra(Q, names)

n = self._quadratic_form.dim()
f = lambda x: self.prod(self._from_dict( {(j,): m[j,i] for j in range(n)},
f = lambda x: self.prod(self._from_dict( {FrozenBitset((j,)): m[j,i] for j in range(n)},
remove_zeros=True )
for i in x)
cat = AlgebrasWithBasis(self.category().base_ring()).Super().FiniteDimensional()
Expand Down

0 comments on commit 0ca83ab

Please sign in to comment.