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

Commit

Permalink
some details about shuffle of words and multizetas
Browse files Browse the repository at this point in the history
  • Loading branch information
fchapoton committed Jan 1, 2022
1 parent c5af195 commit 7229a19
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 63 deletions.
80 changes: 25 additions & 55 deletions src/sage/combinat/words/shuffle_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ def __contains__(self, x):
sage: x*w in w.shuffle(x)
True
"""
from sage.combinat.words.word import Word
if not isinstance(x, Word_class):
return False
if x.length() != self._w1.length() + self._w2.length():
Expand Down Expand Up @@ -177,86 +176,57 @@ def cardinality(self):
len_w2 = self._w2.length()
return binomial(len_w1 + len_w2, len_w1)

def _proc(self, vect):
def __iter__(self):
"""
Return the shuffle of ``w1`` with ``w2`` with 01-vector
``vect``.
The 01-vector of a shuffle is a list of 0s and 1s whose
length is the sum of the lengths of ``w1`` and ``w2``,
and whose `k`-th entry is `1` if the `k`-th letter of
the shuffle is taken from ``w1`` and `0` if it is taken
from ``w2``.
Return an iterator for the words in the
shuffle product of ``w1`` and ``w2``.
EXAMPLES::
sage: from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2
sage: w, u = map(Words("abcd"), ["ab", "cd"])
sage: S = ShuffleProduct_w1w2(w,u)
sage: S._proc([0,1,0,1])
word: cadb
sage: S._proc([1,1,0,0])
word: abcd
sage: S.list() #indirect test
[word: abcd, word: acbd, word: acdb, word: cabd,
word: cadb, word: cdab]
sage: I = Composition([1, 1])
sage: J = Composition([2])
sage: S = ShuffleProduct_w1w2(I, J)
sage: S._proc([1,0,1])
[1, 2, 1]
sage: next(iter(S))
[1, 1, 2]
TESTS:
Sage is no longer confused by a too-restrictive parent
of `I` when shuffling two compositions `I` and `J`
(cf. :trac:`15131`)::
Sage is no longer confused by a too-restrictive parent of `I`
when shuffling compositions `I` and `J` (cf. :trac:`15131`)::
sage: I = Compositions(2)([1, 1])
sage: J = Composition([2])
sage: S = ShuffleProduct_w1w2(I, J)
sage: S._proc([1,0,1])
[1, 2, 1]
sage: S.list()
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]
"""
i1 = -1
i2 = -1
res = []
for v in vect:
if v == 1:
i1 += 1
res.append(self._w1[i1])
else:
i2 += 1
res.append(self._w2[i2])
n1 = len(self._w1)
n2 = len(self._w2)
w1_parent = self._w1.parent()
use_w1_parent = True
try:
return self._w1.parent()(res, check=self._check)
w1_parent(list(self._w1) + list(self._w2), check=self._check)
except (ValueError, TypeError):
# Special situation: the parent of w1 is too
# restrictive to be cast on res.
use_w1_parent = False
if isinstance(self._w1, Composition):
return Composition(res)
large_parent = Composition
elif isinstance(self._w1, Word_class):
return Word(res)
return res

def __iter__(self):
"""
Return an iterator for the words in the
shuffle product of ``w1`` and ``w2``.
EXAMPLES::
sage: from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2
sage: w, u = map(Words("abcd"), ["ab", "cd"])
sage: S = ShuffleProduct_w1w2(w,u)
sage: S.list() #indirect test
[word: abcd, word: acbd, word: acdb, word: cabd,
word: cadb, word: cdab]
"""
n1 = len(self._w1)
n2 = len(self._w2)
large_parent = Word
for iv in IntegerVectors(n1, n1 + n2, max_part=1):
yield self._proc(iv)
it1 = iter(self._w1)
it2 = iter(self._w2)
w = [next(it1) if v else next(it2) for v in iv]
if use_w1_parent:
yield w1_parent(w, check=self._check)
else:
yield large_parent(w)


class ShuffleProduct_shifted(ShuffleProduct_w1w2):
Expand Down
14 changes: 6 additions & 8 deletions src/sage/modular/multiple_zeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,11 +1005,10 @@ def _element_constructor_(self, x):
W = self.basis().keys()
if isinstance(x, list):
x = tuple(x)
return self.monomial(W(x, check=False))
return self._monomial(W(x, check=False))
elif isinstance(parent(x), Multizetas_iterated):
return x.composition()
else:
raise TypeError('invalid input for building a multizeta value')
raise TypeError('invalid input for building a multizeta value')

def algebra_generators(self, n):
"""
Expand Down Expand Up @@ -1544,8 +1543,7 @@ def product_on_basis(self, w1, w2):
sage: M.product_on_basis(y,x)
I(10110) + 3*I(11010) + 6*I(11100)
"""
B = self.basis()
return sum(B[u] for u in shuffle(w1, w2, False))
return self.sum(self._monomial(u) for u in shuffle(w1, w2, False))

def half_product_on_basis(self, w1, w2):
r"""
Expand Down Expand Up @@ -1914,7 +1912,7 @@ def _element_constructor_(self, x):
W = self.basis().keys()
if isinstance(x, list):
x = tuple(x)
return self.monomial(W(x, check=False))
return self._monomial(W(x, check=False))

P = x.parent()
if isinstance(P, Multizetas_iterated):
Expand Down Expand Up @@ -2188,7 +2186,7 @@ def _element_constructor_(self, x):
if w[0] == w[-1] or (len(w) >= 4 and
all(x == w[1] for x in w[2:-1])):
return self.zero()
return self.monomial(w)
return self._monomial(w)

def dual_on_basis(self, w):
"""
Expand Down Expand Up @@ -2257,7 +2255,7 @@ def reversal_on_basis(self, w):
if w[0] == 0 and w[-1] == 1:
return self(w)
W = self.basis().keys()
image = self.monomial(W(list(reversed(w)), check=False))
image = self._monomial(W(list(reversed(w)), check=False))
return -image if len(w) % 2 else image

@lazy_attribute
Expand Down

0 comments on commit 7229a19

Please sign in to comment.