Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/dynamics/interval_exchanges/iet.py
8815 views
1
r"""
2
Interval Exchange Transformations and Linear Involution
3
4
An interval exchage transformation is a map defined on an interval (see
5
help(iet.IntervalExchangeTransformation) for a more complete help.
6
7
EXAMPLES:
8
9
Initialization of a simple iet with integer lengths::
10
11
sage: T = iet.IntervalExchangeTransformation(Permutation([3,2,1]), [3,1,2])
12
sage: print T
13
Interval exchange transformation of [0, 6[ with permutation
14
1 2 3
15
3 2 1
16
17
Rotation corresponds to iet with two intervals::
18
19
sage: p = iet.Permutation('a b', 'b a')
20
sage: T = iet.IntervalExchangeTransformation(p, [1, (sqrt(5)-1)/2])
21
sage: print T.in_which_interval(0)
22
a
23
sage: print T.in_which_interval(T(0))
24
a
25
sage: print T.in_which_interval(T(T(0)))
26
b
27
sage: print T.in_which_interval(T(T(T(0))))
28
a
29
30
There are two plotting methods for iet::
31
32
sage: p = iet.Permutation('a b c','c b a')
33
sage: T = iet.IntervalExchangeTransformation(p, [1, 2, 3])
34
35
.. plot the domain and the range of T::
36
37
sage: T.plot_two_intervals()
38
39
.. plot T as a function::
40
41
sage: T.plot_function()
42
"""
43
from copy import copy
44
from sage.structure.sage_object import SageObject
45
46
from template import side_conversion, interval_conversion
47
48
class IntervalExchangeTransformation(SageObject):
49
r"""
50
Interval exchange transformation
51
52
INPUT:
53
54
- ``permutation`` - a permutation (LabelledPermutationIET)
55
56
- ``lengths`` - the list of lengths
57
58
EXAMPLES:
59
60
Direct initialization::
61
62
sage: p = iet.IET(('a b c','c b a'),{'a':1,'b':1,'c':1})
63
sage: p.permutation()
64
a b c
65
c b a
66
sage: p.lengths()
67
[1, 1, 1]
68
69
Initialization from a iet.Permutation::
70
71
sage: perm = iet.Permutation('a b c','c b a')
72
sage: l = [0.5,1,1.2]
73
sage: t = iet.IET(perm,l)
74
sage: t.permutation() == perm
75
True
76
sage: t.lengths() == l
77
True
78
79
Initialization from a Permutation::
80
81
sage: p = Permutation([3,2,1])
82
sage: iet.IET(p, [1,1,1])
83
Interval exchange transformation of [0, 3[ with permutation
84
1 2 3
85
3 2 1
86
87
If it is not possible to convert lengths to real values an error is raised::
88
89
sage: iet.IntervalExchangeTransformation(('a b','b a'),['e','f'])
90
Traceback (most recent call last):
91
...
92
TypeError: unable to convert x (='e') into a real number
93
94
The value for the lengths must be positive::
95
96
sage: iet.IET(('a b','b a'),[-1,-1])
97
Traceback (most recent call last):
98
...
99
ValueError: lengths must be positive
100
"""
101
def __init__(self,permutation=None,lengths=None):
102
r"""
103
INPUT:
104
105
- ``permutation`` - a permutation (LabelledPermutationIET)
106
107
- ``lengths`` - the list of lengths
108
109
TEST::
110
111
sage: p=iet.IntervalExchangeTransformation(('a','a'),[1])
112
sage: p == loads(dumps(p))
113
True
114
"""
115
from labelled import LabelledPermutationIET
116
if permutation is None or lengths is None:
117
self._permutation = LabelledPermutationIET()
118
self._lengths = []
119
else:
120
self._permutation = permutation
121
self._lengths = lengths
122
123
def permutation(self):
124
r"""
125
Returns the permutation associated to this iet.
126
127
OUTPUT:
128
129
permutation -- the permutation associated to this iet
130
131
EXAMPLES::
132
133
sage: perm = iet.Permutation('a b c','c b a')
134
sage: p = iet.IntervalExchangeTransformation(perm,(1,2,1))
135
sage: p.permutation() == perm
136
True
137
"""
138
return copy(self._permutation)
139
140
def length(self):
141
r"""
142
Returns the total length of the interval.
143
144
OUTPUT:
145
146
real -- the length of the interval
147
148
EXAMPLES::
149
150
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
151
sage: t.length()
152
2
153
"""
154
return sum(self._lengths)
155
156
def lengths(self):
157
r"""
158
Returns the list of lengths associated to this iet.
159
160
OUTPUT:
161
162
list -- the list of lengths of subinterval
163
164
EXAMPLES::
165
166
sage: p = iet.IntervalExchangeTransformation(('a b','b a'),[1,3])
167
sage: p.lengths()
168
[1, 3]
169
"""
170
return copy(self._lengths)
171
172
def normalize(self, total=1):
173
r"""
174
Returns a interval exchange transformation of normalized lengths.
175
176
The normalization consists in multiplying all lengths by a
177
constant in such way that their sum is given by ``total``
178
(default is 1).
179
180
INPUT:
181
182
- ``total`` - (default: 1) The total length of the interval
183
184
OUTPUT:
185
186
iet -- the normalized iet
187
188
EXAMPLES::
189
190
sage: t = iet.IntervalExchangeTransformation(('a b','b a'), [1,3])
191
sage: t.length()
192
4
193
sage: s = t.normalize(2)
194
sage: s.length()
195
2
196
sage: s.lengths()
197
[1/2, 3/2]
198
199
TESTS::
200
201
sage: s = t.normalize('bla')
202
Traceback (most recent call last):
203
...
204
TypeError: unable to convert total (='bla') into a real number
205
sage: s = t.normalize(-691)
206
Traceback (most recent call last):
207
...
208
ValueError: the total length must be positive
209
"""
210
try:
211
float(total)
212
except ValueError:
213
raise TypeError("unable to convert total (='%s') into a real number"
214
% (str(total)))
215
216
if total <= 0:
217
raise ValueError("the total length must be positive")
218
219
res = copy(self)
220
coeff = total / res.length()
221
res._multiply_lengths(coeff)
222
return res
223
224
def _multiply_lengths(self, x):
225
r"""
226
Multiplies the lengths of self by x (no verification on x).
227
228
INPUT:
229
230
- ``x`` - a positive number
231
232
TESTS::
233
234
sage: t = iet.IET(("a","a"), [1])
235
sage: t.lengths()
236
[1]
237
sage: t._multiply_lengths(2)
238
sage: t.lengths()
239
[2]
240
"""
241
self._lengths = map(lambda t: t*x, self._lengths)
242
243
def _repr_(self):
244
r"""
245
A representation string.
246
247
EXAMPLES::
248
249
sage: a = iet.IntervalExchangeTransformation(('a','a'),[1])
250
sage: a # indirect doctest
251
Interval exchange transformation of [0, 1[ with permutation
252
a
253
a
254
"""
255
interval = "[0, %s["%self.length()
256
s = "Interval exchange transformation of %s "%interval
257
s += "with permutation\n%s"%self._permutation
258
return s
259
260
def is_identity(self):
261
r"""
262
Returns True if self is the identity.
263
264
OUTPUT:
265
266
boolean -- the answer
267
268
EXAMPLES::
269
270
sage: p = iet.Permutation("a b","b a")
271
sage: q = iet.Permutation("c d","d c")
272
sage: s = iet.IET(p, [1,5])
273
sage: t = iet.IET(q, [5,1])
274
sage: (s*t).is_identity()
275
True
276
sage: (t*s).is_identity()
277
True
278
"""
279
return self._permutation.is_identity()
280
281
def inverse(self):
282
r"""
283
Returns the inverse iet.
284
285
OUTPUT:
286
287
iet -- the inverse interval exchange transformation
288
289
EXAMPLES::
290
291
sage: p = iet.Permutation("a b","b a")
292
sage: s = iet.IET(p, [1,sqrt(2)-1])
293
sage: t = s.inverse()
294
sage: t.permutation()
295
b a
296
a b
297
sage: t.lengths()
298
[1, sqrt(2) - 1]
299
sage: t*s
300
Interval exchange transformation of [0, sqrt(2)[ with permutation
301
aa bb
302
aa bb
303
304
We can verify with the method .is_identity()::
305
306
sage: p = iet.Permutation("a b c d","d a c b")
307
sage: s = iet.IET(p, [1, sqrt(2), sqrt(3), sqrt(5)])
308
sage: (s * s.inverse()).is_identity()
309
True
310
sage: (s.inverse() * s).is_identity()
311
True
312
"""
313
res = copy(self)
314
res._permutation._inversed()
315
return res
316
317
def __mul__(self, other):
318
r"""
319
Composition of iet.
320
321
The domain (i.e. the length) of the two iets must be the same). The
322
alphabet choosen depends on the permutation.
323
324
TESTS:
325
326
::
327
328
sage: p = iet.Permutation("a b", "a b")
329
sage: t = iet.IET(p, [1,1])
330
sage: r = t*t
331
sage: r.permutation()
332
aa bb
333
aa bb
334
sage: r.lengths()
335
[1, 1]
336
337
::
338
339
sage: p = iet.Permutation("a b","b a")
340
sage: t = iet.IET(p, [1,1])
341
sage: r = t*t
342
sage: r.permutation()
343
ab ba
344
ab ba
345
sage: r.lengths()
346
[1, 1]
347
348
::
349
350
sage: p = iet.Permutation("1 2 3 4 5","5 4 3 2 1")
351
sage: q = iet.Permutation("a b","b a")
352
sage: s = iet.IET(p, [1]*5)
353
sage: t = iet.IET(q, [1/2, 9/2])
354
sage: r = s*t
355
sage: r.permutation()
356
a5 b1 b2 b3 b4 b5
357
b5 a5 b4 b3 b2 b1
358
sage: r.lengths()
359
[1/2, 1, 1, 1, 1, 1/2]
360
sage: r = t*s
361
sage: r.permutation()
362
1b 2b 3b 4b 5a 5b
363
5b 4b 3b 2b 1b 5a
364
sage: r.lengths()
365
[1, 1, 1, 1, 1/2, 1/2]
366
sage: t = iet.IET(q, [3/2, 7/2])
367
sage: r = s*t
368
sage: r.permutation()
369
a4 a5 b1 b2 b3 b4
370
a5 b4 a4 b3 b2 b1
371
sage: r.lengths()
372
[1/2, 1, 1, 1, 1, 1/2]
373
sage: t = iet.IET(q, [5/2,5/2])
374
sage: r = s*t
375
sage: r.permutation()
376
a3 a4 a5 b1 b2 b3
377
a5 a4 b3 a3 b2 b1
378
sage: r = t*s
379
sage: r.permutation()
380
1b 2b 3a 3b 4a 5a
381
3b 2b 1b 5a 4a 3a
382
383
::
384
385
sage: p = iet.Permutation("a b","b a")
386
sage: s = iet.IET(p, [4,2])
387
sage: q = iet.Permutation("c d","d c")
388
sage: t = iet.IET(q, [3, 3])
389
sage: r1 = t * s
390
sage: r1.permutation()
391
ac ad bc
392
ad bc ac
393
sage: r1.lengths()
394
[1, 3, 2]
395
sage: r2 = s * t
396
sage: r2.permutation()
397
ca cb da
398
cb da ca
399
sage: r2.lengths()
400
[1, 2, 3]
401
402
::
403
404
sage: r * s
405
Traceback (most recent call last):
406
...
407
ValueError: self and other are not IET of the same length
408
"""
409
if not(isinstance(other, IntervalExchangeTransformation) and
410
self.length() == other.length()):
411
raise ValueError("self and other are not IET of the same length")
412
413
from labelled import LabelledPermutationIET
414
415
other_sg = other.range_singularities()[1:]
416
self_sg = self.domain_singularities()[1:]
417
418
n_other = len(other._permutation)
419
n_self = len(self._permutation)
420
421
interval_other = other._permutation._intervals[1]
422
interval_self = self._permutation._intervals[0]
423
424
d_other = dict([(i,[]) for i in interval_other])
425
d_self = dict([(i,[]) for i in interval_self])
426
427
i_other = 0
428
i_self = 0
429
430
x = 0
431
l_lengths = []
432
while i_other < n_other and i_self < n_self:
433
j_other = interval_other[i_other]
434
j_self = interval_self[i_self]
435
436
d_other[j_other].append(j_self)
437
d_self[j_self].append(j_other)
438
439
if other_sg[i_other] < self_sg[i_self]:
440
l = other_sg[i_other] - x
441
x = other_sg[i_other]
442
i_other += 1
443
elif other_sg[i_other] > self_sg[i_self]:
444
l = self_sg[i_self] - x
445
x = self_sg[i_self]
446
i_self += 1
447
else:
448
l = self_sg[i_self] - x
449
x = self_sg[i_self]
450
i_other += 1
451
i_self += 1
452
453
l_lengths.append(((j_other,j_self),l))
454
455
alphabet_other = other._permutation.alphabet()
456
alphabet_self = self._permutation.alphabet()
457
458
d_lengths = dict(l_lengths)
459
460
l_lengths = []
461
top_interval = []
462
for i in other._permutation._intervals[0]:
463
for j in d_other[i]:
464
a = alphabet_other.unrank(i)
465
b = alphabet_self.unrank(j)
466
top_interval.append(str(a)+str(b))
467
l_lengths.append(d_lengths[(i,j)])
468
469
bottom_interval = []
470
for i in self._permutation._intervals[1]:
471
for j in d_self[i]:
472
a = alphabet_other.unrank(j)
473
b = alphabet_self.unrank(i)
474
bottom_interval.append(str(a)+str(b))
475
476
p = LabelledPermutationIET((top_interval,bottom_interval))
477
return IntervalExchangeTransformation(p,l_lengths)
478
479
def __eq__(self, other):
480
r"""
481
Tests equality
482
483
TESTS::
484
485
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
486
sage: t == t
487
True
488
"""
489
return (
490
type(self) == type(other) and
491
self._permutation == other._permutation and
492
self._lengths == other._lengths)
493
494
def __ne__(self, other):
495
r"""
496
Tests difference
497
498
TESTS::
499
500
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
501
sage: t != t
502
False
503
"""
504
return (
505
type(self) != type(other) or
506
self._permutation != other._permutation or
507
self._lengths != other._lengths)
508
509
def in_which_interval(self, x, interval=0):
510
r"""
511
Returns the letter for which x is in this interval.
512
513
INPUT:
514
515
- ``x`` - a positive number
516
517
- ``interval`` - (default: 'top') 'top' or 'bottom'
518
519
520
OUTPUT:
521
522
label -- a label corresponding to an interval
523
524
TEST:
525
526
::
527
528
sage: t = iet.IntervalExchangeTransformation(('a b c','c b a'),[1,1,1])
529
sage: t.in_which_interval(0)
530
'a'
531
sage: t.in_which_interval(0.3)
532
'a'
533
sage: t.in_which_interval(1)
534
'b'
535
sage: t.in_which_interval(1.9)
536
'b'
537
sage: t.in_which_interval(2)
538
'c'
539
sage: t.in_which_interval(2.1)
540
'c'
541
sage: t.in_which_interval(3)
542
Traceback (most recent call last):
543
...
544
ValueError: your value does not lie in [0;l[
545
546
.. and for the bottom interval::
547
548
sage: t.in_which_interval(0,'bottom')
549
'c'
550
sage: t.in_which_interval(1.2,'bottom')
551
'b'
552
sage: t.in_which_interval(2.9,'bottom')
553
'a'
554
555
TESTS::
556
557
sage: t.in_which_interval(-2.9,'bottom')
558
Traceback (most recent call last):
559
...
560
ValueError: your value does not lie in [0;l[
561
"""
562
interval = interval_conversion(interval)
563
564
if x < 0 or x >= self.length():
565
raise ValueError("your value does not lie in [0;l[")
566
567
i = 0
568
569
while x >= 0:
570
x -= self._lengths[self._permutation._intervals[interval][i]]
571
i += 1
572
573
i -= 1
574
x += self._lengths[self._permutation._intervals[interval][i]]
575
576
j = self._permutation._intervals[interval][i]
577
return self._permutation._alphabet.unrank(j)
578
579
def singularities(self):
580
r"""
581
The list of singularities of `T` and `T^{-1}`.
582
583
OUTPUT:
584
585
list -- two lists of positive numbers which corresponds to extremities
586
of subintervals
587
588
EXAMPLE::
589
590
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1/2,3/2])
591
sage: t.singularities()
592
[[0, 1/2, 2], [0, 3/2, 2]]
593
"""
594
return [self.domain_singularities(), self.range_singularities()]
595
596
def domain_singularities(self):
597
r"""
598
Returns the list of singularities of T
599
600
OUTPUT:
601
602
list -- positive reals that corresponds to singularities in the top
603
interval
604
605
EXAMPLES::
606
607
sage: t = iet.IET(("a b","b a"), [1, sqrt(2)])
608
sage: t.domain_singularities()
609
[0, 1, sqrt(2) + 1]
610
"""
611
l = [0]
612
for j in self._permutation._intervals[0]:
613
l.append(l[-1] + self._lengths[j])
614
return l
615
616
def range_singularities(self):
617
r"""
618
Returns the list of singularities of `T^{-1}`
619
620
OUTPUT:
621
622
list -- real numbers that are singular for `T^{-1}`
623
624
625
EXAMPLES::
626
627
sage: t = iet.IET(("a b","b a"), [1, sqrt(2)])
628
sage: t.range_singularities()
629
[0, sqrt(2), sqrt(2) + 1]
630
"""
631
l = [0]
632
for j in self._permutation._intervals[1]:
633
l.append(l[-1] + self._lengths[j])
634
return l
635
636
def __call__(self, value):
637
r"""
638
Return the image of value by this transformation
639
640
EXAMPLES::
641
642
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1/2,3/2])
643
sage: t(0)
644
3/2
645
sage: t(1/2)
646
0
647
sage: t(1)
648
1/2
649
sage: t(3/2)
650
1
651
652
TESTS::
653
654
sage: t(-3/2)
655
Traceback (most recent call last):
656
...
657
ValueError: value must positive and smaller than length
658
"""
659
if not(value >= 0 and value < self.length()):
660
raise ValueError("value must positive and smaller than length")
661
662
dom_sg = self.domain_singularities()
663
im_sg = self.range_singularities()
664
665
a = self.in_which_interval(value)
666
667
i0 = self._permutation[0].index(a)
668
i1 = self._permutation[1].index(a)
669
670
return value - dom_sg[i0] + im_sg[i1]
671
672
def rauzy_move(self, side='right', iterations=1):
673
r"""
674
Performs a Rauzy move.
675
676
INPUT:
677
678
- ``side`` - 'left' (or 'l' or 0) or 'right' (or 'r' or 1)
679
680
- ``iterations`` - integer (default :1) the number of iteration of Rauzy
681
moves to perform
682
683
OUTPUT:
684
685
iet -- the Rauzy move of self
686
687
EXAMPLES::
688
689
sage: phi = QQbar((sqrt(5)-1)/2)
690
sage: t1 = iet.IntervalExchangeTransformation(('a b','b a'),[1,phi])
691
sage: t2 = t1.rauzy_move().normalize(t1.length())
692
sage: l2 = t2.lengths()
693
sage: l1 = t1.lengths()
694
sage: l2[0] == l1[1] and l2[1] == l1[0]
695
True
696
"""
697
side = side_conversion(side)
698
699
res = copy(self)
700
for i in range(iterations):
701
res = res._rauzy_move(side)
702
return res
703
704
def _rauzy_move(self,side=-1):
705
r"""
706
Performs a Rauzy move
707
708
INPUT:
709
710
- ``side`` - must be 0 or -1 (no verification)
711
712
TEST::
713
714
sage: t = iet.IntervalExchangeTransformation(('a b c','c b a'),[1,1,3])
715
sage: t
716
Interval exchange transformation of [0, 5[ with permutation
717
a b c
718
c b a
719
sage: t1 = t.rauzy_move() #indirect doctest
720
sage: t1
721
Interval exchange transformation of [0, 4[ with permutation
722
a b c
723
c a b
724
sage: t2 = t1.rauzy_move() #indirect doctest
725
sage: t2
726
Interval exchange transformation of [0, 3[ with permutation
727
a b c
728
c b a
729
sage: t2.rauzy_move() #indirect doctest
730
Traceback (most recent call last):
731
...
732
ValueError: top and bottom extrem intervals have equal lengths
733
"""
734
top = self._permutation._intervals[0][side]
735
bottom = self._permutation._intervals[1][side]
736
737
length_top = self._lengths[top]
738
length_bottom = self._lengths[bottom]
739
740
if length_top > length_bottom:
741
winner = 0
742
winner_interval = top
743
loser_interval = bottom
744
elif length_top < length_bottom:
745
winner = 1
746
winner_interval = bottom
747
loser_interval = top
748
else:
749
raise ValueError("top and bottom extrem intervals have equal lengths")
750
751
res = IntervalExchangeTransformation(([],[]),{})
752
res._permutation = self._permutation.rauzy_move(winner=winner,side=side)
753
res._lengths = self._lengths[:]
754
res._lengths[winner_interval] -= res._lengths[loser_interval]
755
756
return res
757
758
def __copy__(self):
759
r"""
760
Returns a copy of this interval exchange transformation.
761
762
EXAMPLES::
763
764
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
765
sage: s = copy(t)
766
sage: s == t
767
True
768
sage: s is t
769
False
770
"""
771
res = self.__class__()
772
res._permutation = copy(self._permutation)
773
res._lengths = copy(self._lengths)
774
return res
775
776
def plot_function(self,**d):
777
r"""
778
Return a plot of the interval exchange transformation as a
779
function.
780
781
INPUT:
782
783
- Any option that is accepted by line2d
784
785
OUTPUT:
786
787
2d plot -- a plot of the iet as a function
788
789
EXAMPLES::
790
791
sage: t = iet.IntervalExchangeTransformation(('a b c d','d a c b'),[1,1,1,1])
792
sage: t.plot_function(rgbcolor=(0,1,0))
793
"""
794
from sage.plot.all import Graphics
795
from sage.plot.plot import line2d
796
797
G = Graphics()
798
l = self.singularities()
799
t = self._permutation._twin
800
801
for i in range(len(self._permutation)):
802
j = t[0][i]
803
G += line2d([(l[0][i],l[1][j]),(l[0][i+1],l[1][j+1])],**d)
804
805
return G
806
807
def plot_two_intervals(self,
808
position=(0,0),
809
vertical_alignment='center',
810
horizontal_alignment='left',
811
interval_height=0.1,
812
labels_height=0.05,
813
fontsize=14,
814
labels=True,
815
colors=None):
816
r"""
817
Returns a picture of the interval exchange transformation.
818
819
INPUT:
820
821
- ``position`` - a 2-uple of the position
822
823
- ``horizontal_alignment`` - left (defaut), center or right
824
825
- ``labels`` - boolean (defaut: True)
826
827
- ``fontsize`` - the size of the label
828
829
830
OUTPUT:
831
832
2d plot -- a plot of the two intervals (domain and range)
833
834
EXAMPLES::
835
836
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,1])
837
sage: t.plot_two_intervals()
838
"""
839
from sage.plot.all import Graphics
840
from sage.plot.plot import line2d
841
from sage.plot.plot import text
842
from sage.plot.colors import rainbow
843
844
G = Graphics()
845
846
lengths = map(float,self._lengths)
847
total_length = sum(lengths)
848
849
if colors is None:
850
colors = rainbow(len(self._permutation), 'rgbtuple')
851
852
if horizontal_alignment == 'left':
853
s = position[0]
854
elif horizontal_alignment == 'center':
855
s = position[0] - total_length / 2
856
elif horizontal_alignment == 'right':
857
s = position[0] - total_length
858
else:
859
raise ValueError("horizontal_alignement must be left, center or right")
860
861
top_height = position[1] + interval_height
862
for i in self._permutation._intervals[0]:
863
G += line2d([(s,top_height), (s+lengths[i],top_height)],
864
rgbcolor=colors[i])
865
if labels:
866
G += text(str(self._permutation._alphabet.unrank(i)),
867
(s+float(lengths[i])/2, top_height+labels_height),
868
horizontal_alignment='center',
869
rgbcolor=colors[i],
870
fontsize=fontsize)
871
872
s += lengths[i]
873
874
if horizontal_alignment == 'left':
875
s = position[0]
876
elif horizontal_alignment == 'center':
877
s = position[0] - total_length / 2
878
elif horizontal_alignment == 'right':
879
s = position[0] - total_length
880
else:
881
raise ValueError("horizontal_alignement must be left, center or right")
882
883
bottom_height = position[1] - interval_height
884
for i in self._permutation._intervals[1]:
885
G += line2d([(s,bottom_height), (s+lengths[i],bottom_height)],
886
rgbcolor=colors[i])
887
if labels:
888
G += text(str(self._permutation._alphabet.unrank(i)),
889
(s+float(lengths[i])/2, bottom_height-labels_height),
890
horizontal_alignment='center',
891
rgbcolor=colors[i],
892
fontsize=fontsize)
893
s += lengths[i]
894
895
return G
896
897
plot = plot_two_intervals
898
899
def show(self):
900
r"""
901
Shows a picture of the interval exchange transformation
902
903
EXAMPLES::
904
905
sage: phi = QQbar((sqrt(5)-1)/2)
906
sage: t = iet.IntervalExchangeTransformation(('a b','b a'),[1,phi])
907
sage: t.show()
908
"""
909
self.plot_two_intervals().show(axes=False)
910
911
#TODO
912
# class LinearInvolution(SageObject):
913
# r"""_
914
# Linear involutions
915
# """
916
# pass
917
918