Skip to content

Commit bce9bda

Browse files
committed
Fixing typos in _test_semi_infinite.
Adding orbit_types function to automorphism.py
1 parent 69fd49c commit bce9bda

File tree

2 files changed

+57
-66
lines changed

2 files changed

+57
-66
lines changed

scripts/test_quasinormal.py

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,7 @@
22
setup_script(__file__)
33

44
from thompson.word import Word
5+
from thompson.examples import *
56

6-
from thompson.examples import example_4_5 as aut
7-
8-
9-
10-
aut.dump_mapping()
11-
12-
basis = aut.domain
13-
print('basis is', basis)
14-
15-
results = {
16-
Word("x a1 a1 a1", 2, 1) : "left semi-infinite",
17-
Word("x a1 a2", 2, 1) : "right semi-infinite",
18-
Word("x a1 a1 a2", 2, 1) : "complete infinite",
19-
Word("x a2", 2, 1) : "incomplete",
20-
}
21-
22-
for word, expected in results.items():
23-
otype = aut._orbit_type(word, basis)
24-
print(word, 'should have type', expected)
25-
print(otype)
26-
27-
28-
# basis = ex.quasinormal_basis()
29-
# print(basis)
7+
example_4_5.dump_mapping()
8+
orbit_types(example_4_5, example_4_5.domain)

thompson/automorphism.py

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from thompson.word import Word
1515
"""
1616

17-
__all__ = ["Automorphism", "Orbit"]
17+
__all__ = ["Automorphism", "Orbit", "orbit_types"]
1818

1919
from collections import deque
2020
from enum import Enum
@@ -381,62 +381,58 @@ def _orbit_type(self, y, basis):
381381
"""Returns the orbit type of *y* with respect to the given *basis*.
382382

383383
>>> from thompson.examples import *
384-
>>> def f(word, aut, basis=None):
385-
... if basis is None:
386-
... basis = aut._minimal_expansion()
387-
... print(aut._orbit_type(word, basis))
388-
389384
>>> #Example 4.5.
390-
>>> for w in ["x", "x a1", "x a1 a1", "x a1 a1 a1", "x a1 a1 a2", "x a1 a2", "x a2", "x a1 a1 a1 a1 a2 a2 a1 a2 a1"]:
391-
... f(Word(w, 2, 1), example_4_5, example_4_5.domain)
392-
Orbit.incomplete
393-
Orbit.incomplete
394-
Orbit.left_semi_infinite
395-
Orbit.left_semi_infinite
396-
Orbit.complete_infinite
397-
Orbit.right_semi_infinite
398-
Orbit.incomplete
399-
Orbit.complete_infinite
385+
>>> orbit_types(example_4_5, example_4_5.domain)
386+
x1 a1 a1 a1: Orbit.left_semi_infinite
387+
x1 a1 a1 a2: Orbit.complete_infinite
388+
x1 a1 a2: Orbit.right_semi_infinite
389+
x1 a2 a1: Orbit.complete_finite
390+
x1 a2 a2: Orbit.complete_finite
391+
with respect to the basis [x1 a1 a1 a1, x1 a1 a1 a2, x1 a1 a2, x1 a2 a1, x1 a2 a2]
392+
>>> orbit_types(example_4_5, basis=example_4_5.domain, words=['x', 'x a1', 'x a2'])
393+
x: Orbit.incomplete
394+
x a1: Orbit.incomplete
395+
x a2: Orbit.incomplete
396+
with respect to the basis [x1 a1 a1 a1, x1 a1 a1 a2, x1 a1 a2, x1 a2 a1, x1 a2 a2]
400397

401398
>>> #Example 4.11
402-
>>> for w in ["x1 a1", "x1 a2"]:
403-
... f(Word(w, 2, 1), example_4_11)
404-
Orbit.left_semi_infinite
405-
Orbit.right_semi_infinite
399+
>>> orbit_types(example_4_11)
400+
x1 a1: Orbit.left_semi_infinite
401+
x1 a2: Orbit.right_semi_infinite
402+
with respect to the basis [x1 a1, x1 a2]
406403

407404
>>> #Example 4.12
408405
>>> basis = example_4_12._minimal_expansion()
409-
>>> for w in basis:
410-
... print(w, ':', sep='', end=' ')
411-
... f(Word(w, 2, 1), example_4_12, basis)
412-
Orbit.incomplete
413-
Orbit.incomplete
406+
>>> orbit_types(example_4_12, basis)
407+
x1 a1: Orbit.incomplete
408+
x1 a2: Orbit.incomplete
409+
with respect to the basis [x1 a1, x1 a2]
414410
>>> basis.expand(0)
415-
>>> for w in basis:
416-
... print(w, ':', sep='', end=' ')
417-
... f(Word(w, 2, 1), example_4_12, basis)
411+
>>> orbit_types(example_4_12, basis)
418412
x1 a1 a1: Orbit.complete_infinite
419413
x1 a1 a2: Orbit.complete_infinite
420414
x1 a2: Orbit.incomplete
415+
with respect to the basis [x1 a1 a1, x1 a1 a2, x1 a2]
421416
>>> basis.expand(2)
422-
>>> for w in basis:
423-
... print(w, ':', sep='', end=' ')
424-
... f(Word(w, 2, 1), example_4_12, basis)
425-
x1 a1 a1: Orbit.complete_infinite
426-
x1 a1 a2: Orbit.complete_infinite
427-
x1 a2 a1: Orbit.complete_infinite
428-
x1 a2 a2: Orbit.complete_infinite
417+
>>> orbit_types(example_4_12, basis)
418+
x1 a1 a1: Orbit.complete_finite
419+
x1 a1 a2: Orbit.complete_finite
420+
x1 a2 a1: Orbit.complete_finite
421+
x1 a2 a2: Orbit.complete_finite
422+
with respect to the basis [x1 a1 a1, x1 a1 a2, x1 a2 a1, x1 a2 a2]
429423
"""
430-
#TODO. Tests from the examples
431424
# print('Forward Orbit for', y)
425+
# input()
432426
right_infinite = self._test_semi_infinite(y, basis, backward=False)
433427
if isinstance(right_infinite, Orbit):
434428
return right_infinite #periodic
435429
# print('right_infinite:', right_infinite)
436430

437431
# print('Backward orbit for', y)
432+
# input()
438433
left_infinite = self._test_semi_infinite(y, basis, backward=True)
439434
assert not isinstance(left_infinite, Orbit), "Orbit is not periodic going forward but is going backward."
435+
# print('left_infinite:', left_infinite)
440436

441437
if right_infinite and left_infinite:
442438
return Orbit.complete_infinite
@@ -449,10 +445,12 @@ def _orbit_type(self, y, basis):
449445

450446
#TODO maybe this should return characteristics as well
451447
def _test_semi_infinite(self, y, basis, backward=False):
452-
"""Computes the orbit type of *y* with respect to *basis* in the forward direction. (Use ``backward=True`` to go backwards.)"""
453-
i = 0
448+
"""Computes the orbit type of *y* with respect to *basis* in the forward direction. (Use ``backward=True`` to go backwards.) Returns Orbit.complete_finite if a periodic orbit in X<A> is found; otherwise returns True or false to say if the orbit in X<A> is semi-infinite in the given direction."""
454449
image = y
455450
images = [y]
451+
#y is the starting element
452+
#image is the ith image under self of y
453+
#images is the list of previous images, starting at y = image #0 and ending at image #i-1
456454
while True:
457455
#Compute the image y\phi^i as y\phi^{i-1} \phi
458456
image = self.image(image, inverse=backward)
@@ -463,22 +461,36 @@ def _test_semi_infinite(self, y, basis, backward=False):
463461

464462
#2. Look for basis elements which are prefixes of the new image
465463
prefixes = [gen for gen in basis if gen.is_above(image)]
466-
464+
# print('From the basis, we found potential {} prefix(es) for ``image``'.format(len(prefixes)))
465+
# print(prefixes)
466+
# print('Previous images were', images)
467467
#3. For each previous image:
468468
for previous in images:
469+
# print('previous image', previous)
469470
#Is this the same as the word we've just computed?
470471
if previous == image:
471472
return Orbit.complete_finite #Perodic and infinite in both directions.
472-
#Otherwise, is there a generator which is an initial segment of both the previous and current images?
473+
#Check all the basis elements above the current image.
474+
#Is there a generator above any previous images?
473475
for generator in prefixes:
474-
tail = generator.test_above(image)
476+
tail = generator.test_above(previous)
475477
if tail is not None:
476478
#We've found a match: both *image* and *previous* start with *generator*
477479
return True #IS semi_infinite in the given direction
478-
images.append(y)
480+
images.append(image)
479481

480482

481483
#TODO. Compose and invert automorphisms. Basically move all the functionality from TreePair over to this class and ditch trree pair.
482484
#TODO method to decide if the automorphism is in (the equivalent of) F, T, or V.
483485
#TODO the named elements A, B, C, X_n of Thompson's V.
484486

487+
def orbit_types(aut, basis=None, words=None):
488+
r"""Prints the classification of the orbits under *aut* of each word in *words* with respect to *basis*. If *basis* is omitted, it is taken to be the minimal expansion given by :meth:`~thompson.automorphism._minimal_expansion`. If *words* is omited, it is taken to be the same as *basis*. See the docstring for :meth:`~thompson.automorphism._orbit_type`"""
489+
if basis is None:
490+
basis = aut._minimal_expansion()
491+
if words is None:
492+
words = basis
493+
for w in words:
494+
print(w, ':', sep='', end=' ')
495+
print(aut._orbit_type(w, basis))
496+
print('with respect to the basis', basis)

0 commit comments

Comments
 (0)