#30243 closed enhancement (fixed)

Enumeration and manipulation of fully commutative elements in Coxeter groups

Reported by: gh-cemulate Owned by:
Priority: minor Milestone: sage-9.2
Component: combinatorics Keywords: Coxeter systems, Coxeter groups, fully commutative elements
Cc: gfeinberg, tscrim, combinat Merged in:
Authors: Chase Meadors, Tianyuan Xu Reviewers: Travis Scrimshaw
Report Upstream: N/A Work issues:
Branch: 56d093f (Commits, GitHub, GitLab) Commit: 56d093fc63ec8117bf9fdbd1faf6a5fe979b6f7f
Dependencies: Stopgaps:

Status badges

Description (last modified by gh-cemulate)

The purpose of the enhancement is to enumerate and manipulate the fully commutative (FC) elements in a Coxeter group. In particular, it accomplishes the goal of determining if a group element is FC set in Ticket: 25964.

The enhancement resides in one new file src/sage/combinat/fully_commutative_elements.py, with examples and tests included for every class and method. All other changes in this ticket concern only meta information such as bibliography references and documentation.

The file src/sage/combinat/fully_commutative_elements.py follows the standard parent-element pattern in Sage and contains two classes FullyCommutativeElements and FullyCommutativeElement, both introduced into the global namespace. Instances of FullyCommutativeElements are implemented in the category of enumerated sets and refined to either finite or infinite enumerated sets for groups associated to Cartan types. Each instance of FullyCommutativeElement is realized as a NormalizedClonableList via the Cartier--Foata canonical form of FC elements.

Basic usage for enumeration of FC elements in a Coxeter group.

sage: FCA3 = FullyCommutativeElements(['A', 3]); FCA3
Fully commutative elements in Coxeter system with Cartan type ['A', 3]
sage: FCA3.category()
Category of finite enumerated sets
sage: FCA3.list()
[[],
 [1],
 [2],
 [3],
 [2, 1],
 [1, 3],
 [1, 2],
 [3, 2],
 [2, 3],
 [3, 2, 1],
 [2, 1, 3],
 [1, 3, 2],
 [1, 2, 3],
 [2, 1, 3, 2]]

sage: FCAffineA2 = FullyCommutativeElements(['A', 2, 1])
sage: FCAffineA2.category()
Category of infinite enumerated sets
sage: list(FCAffineA2.iterate_to_length(4))
[[], [0], [1], [2], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1,2], [2, 1, 0], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], [0, 1, 2], [0, 2, 1, 0], [0, 1, 2, 0], [1, 2, 0, 1], [1, 0, 2, 1], [2, 1,0, 2], [2, 0, 1, 2]]
sage: FCB8 = FullyCommutativeElements(['B', 8])
sage: len(FCB8)    # long time (7 seconds)
14299

Elements are verified to be FC upon construction, and FC element are normalized to Cartier--Foata canonical form:

sage: FCA3([1,2,1])
Traceback (most recent call last):
...
ValueError: The input is not a reduced word of a fully commutative element.

sage: FCA3([2, 3, 1, 2])
[2, 1, 3, 2]

In addition to the construction and enumeration of FC elements in a Coxeter group, various methods are developed for each FC element, including tools for studying the heap posets of FC elements and for computing Kazhdan and Lusztig's (generalized) star operations on FC elements. For more details, please see the attached documentation page built by Sage.

Attachments (1)

FullyCommutativeElements.pdf (267.1 KB) - added by gh-cemulate 16 months ago.
Built documentation page

Download all attachments as: .zip

Change History (48)

comment:1 Changed 16 months ago by gh-cemulate

  • Branch set to u/gh-cemulate/fully_commutatve_elements

comment:2 Changed 16 months ago by gh-cemulate

  • Authors set to Chase Meadors, Tianyuan Xu
  • Commit set to f7811f380d55431fc8c197369d43165e1ef2de38
  • Component changed from PLEASE CHANGE to combinatorics
  • Description modified (diff)
  • Keywords fully commutative coxeter CoxeterGroup added
  • Priority changed from major to minor
  • Type changed from PLEASE CHANGE to enhancement

comment:3 Changed 16 months ago by gh-cemulate

  • Description modified (diff)

comment:4 Changed 16 months ago by git

  • Commit changed from f7811f380d55431fc8c197369d43165e1ef2de38 to df550617f31c70803d26ea2711ae2c9b8cf6326e

Branch pushed to git repo; I updated commit sha1. New commits:

df55061Remove spaces before code block indicator

comment:5 Changed 16 months ago by gh-cemulate

  • Status changed from new to needs_review

comment:6 Changed 16 months ago by gh-cemulate

  • Summary changed from fully-commutatve-elements to Support for the enumeration and manipulation of fully commutative elements in a Coxeter system

comment:7 Changed 16 months ago by git

  • Commit changed from df550617f31c70803d26ea2711ae2c9b8cf6326e to f711d9a0d45761d80271668868c737a5457f3190

Branch pushed to git repo; I updated commit sha1. New commits:

f711d9aChange error messages to match Python convention.

comment:8 Changed 16 months ago by gh-cemulate

  • Description modified (diff)

comment:9 Changed 16 months ago by gh-TianyuanX

  • Cc gfeinberg tscrim combinat added
  • Description modified (diff)
  • Keywords Coxeter systems Coxeter groups elements added; coxeter CoxeterGroup removed
  • Summary changed from Support for the enumeration and manipulation of fully commutative elements in a Coxeter system to Enumeration and manipulation of fully commutative elements in Coxeter groups

comment:10 Changed 16 months ago by git

  • Commit changed from f711d9a0d45761d80271668868c737a5457f3190 to 42fb3ba13c74147b1b2944c50e84ac6833724771

Branch pushed to git repo; I updated commit sha1. New commits:

40614a1Remove unused variable
455428fRearrange some misplaced docs
9044364Have .check() not return anything
191b7abRefactor .check() and .is_fully_commutative() to be more semantically correct.
dd94864Add _repr_ for parent class
42fb3baAchieve 100% test coverage

comment:11 Changed 16 months ago by gh-cemulate

  • Description modified (diff)

Changed 16 months ago by gh-cemulate

Built documentation page

comment:12 Changed 16 months ago by tscrim

The test for an element of a Coxeter group to be fully commutative should also be available for the elements of a Coxeter group (probably in the category of CoxeterGroups).

FullyCommutativeElements should also be a UniqueRepresentation. So you will also need to implement

@staticmethod
    def __classcall_private__(cls, data):
        if isinstance(data, CoxeterMatrix):
            matrix = data
        else:
            try:
                t = CartanType(data)
            except (TypeError, ValueError):
                raise ValueError('input must be a CoxeterMatrix or data describing a Cartan/Coxeter type')
            matrix = t.coxeter_matrix()
        return super(cls, FullyCommutativeElements).__classcall__(cls, matrix)

    def __init__(self, matrix):
        self._matrix = matrix
        # Rest of the initialization

I would also avoid the big try-except block in the __init__ to handle more cases more explicitly. (This will make it easier to maintain the code later on.) I think you should also see if the data can be passed to a CoxeterType, possibly first before CartanType.

comment:13 Changed 16 months ago by tscrim

Actually, rather than the Coxeter matrix, it should have the Coxeter group as the input. That way it can immediately output the actual group elements (which can depend on your group's implementation) rather than converting from the reduced words. It just saves a little bit of time for the user, and I think that is more natural anyways.

Finally, I would add a hook in the category of Coxeter groups of

def fully_commutative_elements(self):
    from sage.combinat.fully_commutative_elements import FullyCommutativeElements
    return FullyCommutativeElements(self)

That way it is easy to access and more natural than having something in the global namespace (which I might even say should be removed).

comment:14 Changed 16 months ago by gh-cemulate

I like the idea of exposing everything as CoxeterGroup.fully_commutative_elements(). And implementing UniqueRepresentation? should be fine as well. I'll get this done shortly.

The reason we differentiated the element class from the elements of a CoxeterGroup in the first place is that we're treating all of our operations and manipulations on elements as pure combinatorics on reduced words; depending on the implementation, calling .(from_)reduced_word() all the time can be quite expensive. Furthermore, we replace methods on CoxeterGroup elements such as has_descent and co. to provide specialized criterion that work on fully commutative reduced words, and add various other methods as well. This is why we ended up inventing a lightweight element class that simply represents "a canonical reduced word of a fully commutative element".

I agree it might be nice to be able to go seamlessly to an element of the ambient CoxeterGroup (if we're going to initialize with a CoxeterGroup as the "core data" instead of a matrix, which I like), but perhaps we could just have something like .element() that forgets the full commutivity and gives you a regular element of the CoxeterGroup?

comment:15 Changed 16 months ago by git

  • Commit changed from 42fb3ba13c74147b1b2944c50e84ac6833724771 to dfae2719f9e432fecd4a3e1bcc48347e184c8f82

Branch pushed to git repo; I updated commit sha1. New commits:

da4d47dAdd .type() accessor to CoxeterType
a3d02fdImplement unique representation and redesign initialization a bit.
403fca9Remove FullyCommutativeElements from global namespace and expose through CoxeterGroup.
dfae271Fix tests to reflect new usage method.

comment:16 Changed 16 months ago by git

  • Commit changed from dfae2719f9e432fecd4a3e1bcc48347e184c8f82 to b1e3db538a332c1b8470d2176629e663b5e05ebb

Branch pushed to git repo; I updated commit sha1. New commits:

b1e3db5Add .group_element() method on fully commutative elements.

comment:17 Changed 16 months ago by git

  • Commit changed from b1e3db538a332c1b8470d2176629e663b5e05ebb to d4f53de6ef04cdc572aacad4e8dcc8bcb4bedca9

Branch pushed to git repo; I updated commit sha1. New commits:

552fa0cRemove superfluous accessors
1319113Typo in rank for FC-finite classification.
d4f53deImprove comments on category refinement.

comment:18 Changed 16 months ago by git

  • Commit changed from d4f53de6ef04cdc572aacad4e8dcc8bcb4bedca9 to 5cbdca30bbbc372c29b5f310f95acb15dac4d17a

Branch pushed to git repo; I updated commit sha1. New commits:

5cbdca3Improve unique representation test.

comment:19 Changed 16 months ago by gh-cemulate

Alright, we've taken care of most of your suggestions:

  • In implementing unique representation, we've gone ahead and moved to your idea of a CoxeterGroup being the "core data" that a FullyCommutativeElements is initialized from. In doing so, we've restructured the initialization and category refinement steps to be a little more straightforward. To do so we had to add a .type() accessor to CoxeterType? in combinat/root_system/coxeter_type.py, which was missing; hopefully that's no big deal. With this change we are now able to use CoxeterType throughout and not mention CartanType at all.
  • We've removed FullyCommutativeElements from the global namespace; usage is now via CoxeterGroup(...).fully_commutative_elements(). All docs and tests have been changed to reflect this.
  • We've added a .group_element() to get the plain Coxeter group element from a FullyCommutativeElement. This is in the spirit of your earlier suggestion that we should be able to "output the actual group element", although maybe not the "immediately" part: if w is an instance of FullyCommutativeElement, then w itself is not to be viewed as an element of a Coxeter group in the sense of categories/coxeter_group.py; as such, ElementMethods like cover_reflections() from sage.categories.coxeter_groups make sense for w.group_element() but not for w, while methods like .cartier_foata_form() or .star_operation() from fully_commutative_elements.py are defined for w but not for w.group_element(). The methods in coxeter_groups.py and fully_commutative_elements.py seem to overlap only in some code about descents (though coset_representative from the former and coset_decomposition from the latter are also related), so maybe it's fine to keep the two worlds somewhat separate? We are open to other schemes with more thorough integration. Please let us know what you think.

comment:20 Changed 16 months ago by tscrim

Sorry for the delay in responding; last week was super busy for me.

Hmm.. I that is a fair point with wanting to abstract away the group and just consider reduced words themselves. I like this current implementation that takes the best of both words: the abstraction and the link with a specific implementation of the group.


Some additional changes:

Minor point, but can you use the standard copyright for Sage:

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#                  https://www.gnu.org/licenses/
# ****************************************************************************

This is better in terms of the internal structure:

-class FullyCommutativeElements(Parent, UniqueRepresentation):
+class FullyCommutativeElements(UniqueRepresentation, Parent):

This check is not correct:

if not ctype.is_affine() or (family == 'F' and rank == 5) or (family == 'E' and rank == 9):

This says an indefinite type will have finitely many FC elements. This does not seem to match what is in the comment. I also don't like relying on is_affine() failing to check for indefinite type. That feels fragile.

The __iter__ can be simplified a bit:

         # To make the iterator deterministic, use a dictionary rather than a
         # set, for the keys are then ordered by default by Python 3.7+:
         recent_words = {empty_word: True}
         yield empty_word
-        length = 1
-        while True:
+        while recent_words:
             new_words = {}
-            for w in recent_words.keys():
+            for w in recent_words:
                 for s in letters:
                     if w.still_reduced_fc_after_prepending(s):
                         sw = self.element_class(
                             self, [s] + list(w), check=False)
                         # "Add" sw to the "set"
                         new_words[sw] = True
-            if len(new_words) == 0:
                 return
-            for w in new_words.keys():
+            for w in new_words:
                 yield w
             recent_words = new_words
-            length += 1

It might also be good to say in the docstring that it iterates by increasing length.

In iterate_to_length, I would remove the assert length >= 0 since it doesn't match your docstring. Also

         INPUT:
 
-        - ``length`` -- integer; maximum length of element to generate.
+        - ``length`` -- integer; maximum length of element to generate

The .. PLOT:: is causing the docbuild to fail. I think you need to do this

         .. PLOT::
+            :width: 400 px
 
-            FC = FullyCommutativeElements(['B', 5])
+            FC = CoxeterGroup(['B', 5]).fully_commutative_elements()
             g = FC([3,2,4,3,1]).plot_heap()
             sphinx_plot(g)

comment:21 Changed 16 months ago by git

  • Commit changed from 5cbdca30bbbc372c29b5f310f95acb15dac4d17a to a50966505c8dab8063b07aef349c9b7b856c09ce

Branch pushed to git repo; I updated commit sha1. New commits:

d0c4648Fix docs
a91e1caClean up iterator
a509665Standardize class inheritance; remove length assertion.

comment:22 Changed 16 months ago by gh-cemulate

No problem, thanks for the comments. I've taken care of all the issues you mentioned and verified that the docs build successfully now.

comment:23 Changed 16 months ago by git

  • Commit changed from a50966505c8dab8063b07aef349c9b7b856c09ce to b174c03c6cccc39e46b316c132db286af78df461

Branch pushed to git repo; I updated commit sha1. New commits:

b174c03Patch up FC-finite/infinite detection.

comment:24 Changed 16 months ago by gh-cemulate

We had forgotten to address your comment about the FC-finite/infinite check, but we think it's more sound now. We're not entirely sure what you mean by "indefinite type", but now we do not mention affine at all, as it shouldn't be necessary.

comment:25 Changed 16 months ago by tscrim

An indefinite type is something that is not finite nor affine.

However, there are still issues with reducible types:

sage: CT = CoxeterType('F4xA2')
sage: CT.is_finite()
True
sage: CT.type()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
...

An is_reducible method is missing from CoxeterType as well, but the output of type() will be 'reducible'.

You also forgot to fix the copyright statement.

Also, one docstring fix:

         def fully_commutative_elements(self):
             r"""
-            Return the combinatorial class of fully commutative elements in this
-            Coxeter group. See
-            :class:`~sage.combinat.fully_commutative_elements.FullyCommutativeElements`
-            for details.
+            Return the set of fully commutative elements in this Coxeter group.
+
+            .. SEEALSO::
+
+                :class:`~sage.combinat.fully_commutative_elements.FullyCommutativeElements`

comment:26 Changed 16 months ago by git

  • Commit changed from b174c03c6cccc39e46b316c132db286af78df461 to 64f22b2cff0e12dde96e35a209b6ca13b197997b

Branch pushed to git repo; I updated commit sha1. New commits:

fee70cbFix docs
64f22b2Use standard Sage copyright

comment:27 Changed 16 months ago by git

  • Commit changed from 64f22b2cff0e12dde96e35a209b6ca13b197997b to b974c6ebdabf601a5e1c57cfc6eed1497489875f

Branch pushed to git repo; I updated commit sha1. New commits:

b974c6eRedesign FC-finite/infinite detection

comment:28 Changed 16 months ago by gh-cemulate

I've taken another stab at the category refinement step. I believe now it correctly refines to .Finite() or Infinite() in the finite or affine case, while not bothering / doing nothing in all remaining cases, which includes indefinite types and reducible types.

I hope I understood your previous comment correctly; the only issue I took away from that is that we may incorrectly report the finite/infinite status of reducible or indefinite types. I was able to construct the FC elements for various product types and manipulate them just fine without any exceptions being thrown (the exception in your example session does not happen for me, as the addition of CoxeterType.type() resolves that).

comment:29 Changed 16 months ago by tscrim

I don't see why you cannot handle reducible types. I believe the FC elements in a reducible type is just the product of each of the FC elements in each irreducible component. So a reducible type is finite if and only if all of its irreducible components are finite. So how I would do it would be like this:

is_finite = True
if ctype.is_reducible():
    ctype = ctype.component_types()
else:
    ctype = [ctype]
for ct in ctype:
    if not is_a_finite_FC_type(ct):
        is_finite = False
        break
if is_finite:
    category = category.Finite()
else:
    category = category.Infinite()

You would need to add a few more little features to CoxeterType that I should have already added (but didn't think about as I didn't need it for my application at that time). However, they are all basically just redirects.

comment:30 Changed 16 months ago by git

  • Commit changed from b974c6ebdabf601a5e1c57cfc6eed1497489875f to 46e732a9ad77f7275cbf857616091a7bfcc4a37e

Branch pushed to git repo; I updated commit sha1. New commits:

0bd7911Add more methods to CoxeterType
46e732aRedesign FC-finite/infinite detection.

comment:31 Changed 16 months ago by gh-cemulate

Ah, I see your point; agreed.

I've redone it again, this time I think it's more straightforward. I was also able to do away with the try-catch block, as CoxeterGroup.coxeter_type() will be a CoxeterMatrix (which inherits from CoxeterType) in the indefinite case, and a CoxeterType when it is able to be detected as such. I believe this is a sound approach but let me know if I've made any faulty assumptions.

comment:32 Changed 16 months ago by tscrim

Thank you, it is looking a lot better. Now one last bit is you can simplify the checking for the infinite case by making it a positive statement:

if (not ctype.is_finite() and
    not ((family == 'F' and rank == 5) or (family == 'E' and rank == 9))):
    is_finite = False
    break

IMO, this makes the code easier to read.

comment:33 Changed 16 months ago by git

  • Commit changed from 46e732a9ad77f7275cbf857616091a7bfcc4a37e to 8263261b82f6c436ccf09fe0ba0d936a9aa31c50

Branch pushed to git repo; I updated commit sha1. New commits:

2bd2cb6Make FC-finite/infinite detection more straightforward.
8263261Add tests for cardinality detection.

comment:34 Changed 16 months ago by git

  • Commit changed from 8263261b82f6c436ccf09fe0ba0d936a9aa31c50 to dd642fe4e334d98dba1c8ea37cf2e9802add78f4

Branch pushed to git repo; I updated commit sha1. New commits:

dd642feRemove extra comment.

comment:35 Changed 16 months ago by gh-cemulate

OK, I've made it more straightforward and added some tests for the cardinality detection as well.

comment:36 Changed 16 months ago by tscrim

Thank you. The finite detection looks great now. We are almost there.

I would just simply have normalize = cartier_foata_form rather than an explicit redirect. This becomes moot, but why is normalize even returning something when the cartier_foata_form returns nothing? Likewise moot, but you don't need to explicitly state the redirects.

I would hide still_reduced_fc_after_prepending by renaming it _still_reduced_fc_after_prepending as the user doesn't really need that method.

Instead of \mathbb{N}, you can use \NN, which is better for standardization within Sage. (This applies to anything similar, such at \ZZ and \QQ.)

Remove OPTIONAL ARGUMENTS:; just include them in the INPUT: block. Also, input items should not end with a period/full-stop. Additionally, please format as ``'left'``.

You probably want this:

             (3) `t` is left descent of the word `u_3`  obtained by
             removing the leftmost `s` from `u_2`;
+
             ...
+
             (m-1) the appropriate element in `\{s, t\}` is a left descent
             of the word `u_{m-1}` obtained by removing the leftmost letter
             required to be a descent in Condition (m-2) from `u_{m-2}`.

I think this is much more understandable on 1 line (and therefore worth breaking the 80 char/line guideline):

-            new_string = [other] + \
-                cur_string if side == 'left' else cur_string + [other]
+            new_string = [other] + cur_string if side == 'left' else cur_string + [other]

In the FullyCommutativeElements.__init__, I would make the doctests:

    def __init__(self, coxeter_group):
        r"""
        Initialize ``self``.

        EXAMPLES::

            sage: from sage.combinat.fully_commutative_elements import FullyCommutativeElements
            sage: FC = FullyCommutativeElements(CoxeterGroup(['H', 4]))
            sage: TestSuite(FC).run()
        """

{{{#diff

sage: list(FCAffineA2.iterate_to_length(4))

  • [[], [0], [1], [2], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1,
  • 2], [2, 1, 0], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], [0, 1,
  • 2], [0, 2, 1, 0], [0, 1, 2, 0], [1, 2, 0, 1], [1, 0, 2, 1], [2, 1,
  • 0, 2], [2, 0, 1, 2]]

+ [[], [0], [1], [2], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], + [1, 2], [2, 1, 0], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], + [0, 1, 2], [0, 2, 1, 0], [0, 1, 2, 0], [1, 2, 0, 1], + [1, 0, 2, 1], [2, 1, 0, 2], [2, 0, 1, 2]] }}}

comment:37 Changed 16 months ago by git

  • Commit changed from dd642fe4e334d98dba1c8ea37cf2e9802add78f4 to 89705b006cf8a6e9ae3ee3d95fdca63c7bd17b97

Branch pushed to git repo; I updated commit sha1. New commits:

a6e00aaStandardize TeX in docstrings
a1b56afMake still_reduced_fc_after_prepending private.
d4b00b6Clean up docstrings
84c3b00Remove periods from input items in docstrings.
4f37586Don't break lines in ternary expressions.
bc2c7dbUse TestSuite for __init__ doctests.
34e3d02Clean up formatting on some long-output doctests
df500f4More string literals that should be in code delimiters.
89705b0Eliminate `cartier_foata_form` and just use `normalize`, instead of redirecting.

comment:38 Changed 16 months ago by gh-cemulate

Alright, I believe I've addressed all your concerns. I did take care to fix other instances that were similar to the cases you pointed out when possible, and verified the docs build and look OK.

Per the first suggestion, I eliminated cartier_foata_form and simply kept normalize; I think we were concerned that "normalize" isn't very descriptive, but given that the docstring says exactly how we are normalizing, I don't think it's a problem.

comment:39 Changed 16 months ago by tscrim

Thank you. Last tidbits:

The docstring of normalize is not correct because you are not returning anything. I would say

Mutate ``self`` into Cartier-Foata normal form.

(the single hyphen is because this doesn't convert it to latex, sadly).

I missed this when reading the docstring, but in coset_decomposition, I would change l to \ell so there is no possible confusion with 1 or I (plus IMO, the latex version is prettier).

comment:40 Changed 16 months ago by git

  • Commit changed from 89705b006cf8a6e9ae3ee3d95fdca63c7bd17b97 to 5d3a953a8cc268bf22dbd2eff18dfd8afce8ffa4

Branch pushed to git repo; I updated commit sha1. New commits:

5d3a953More docstring tweaks

comment:41 Changed 16 months ago by gh-cemulate

I agree; taken care of.

comment:42 Changed 16 months ago by tscrim

  • Reviewers set to Travis Scrimshaw
  • Status changed from needs_review to positive_review

Thank you.

comment:43 Changed 16 months ago by gh-cemulate

No problem, thanks a lot for your time and effort; we appreciate the feedback! This will help inform us on code style and Sage convention for any future submissions.

comment:44 Changed 15 months ago by git

  • Commit changed from 5d3a953a8cc268bf22dbd2eff18dfd8afce8ffa4 to 56d093fc63ec8117bf9fdbd1faf6a5fe979b6f7f
  • Status changed from positive_review to needs_review

Branch pushed to git repo; I updated commit sha1 and set ticket back to needs_review. New commits:

56d093fFix pyflakes failure

comment:45 Changed 15 months ago by gh-cemulate

I checked the test failures and fixed a pyflakes error.

comment:46 Changed 15 months ago by tscrim

  • Status changed from needs_review to positive_review

comment:47 Changed 15 months ago by vbraun

  • Branch changed from u/gh-cemulate/fully_commutatve_elements to 56d093fc63ec8117bf9fdbd1faf6a5fe979b6f7f
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.