# Matrix Cocycles¶

Matrix cocyles

EXAMPLES:

The 1-cylinders of ARP transformation given as matrices:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: zip(*ARP.n_cylinders_iterator(1))
[(word: 1,
word: 2,
word: 3,
word: 123,
word: 132,
word: 213,
word: 231,
word: 312,
word: 321),
(
[1 1 1]  [1 0 0]  [1 0 0]  [1 0 1]  [1 1 0]  [1 1 1]  [2 1 1]  [1 1 1]
[0 1 0]  [1 1 1]  [0 1 0]  [1 1 1]  [1 2 1]  [0 1 1]  [1 1 0]  [1 2 1]
[0 0 1], [0 0 1], [1 1 1], [1 1 2], [1 1 1], [1 1 2], [1 1 1], [0 1 1],
<BLANKLINE>
[2 1 1]
[1 1 1]
[1 0 1]
)]


Ces calculs illustrent le bounded distorsion de ratio=4 pour ARP multiplicatif (2 avril 2014):

sage: T = cocycles.Sorted_ARPMulti(2)
sage: T.distorsion_max(1, p=oo)
5
sage: T.distorsion_max(2, p=oo)
7
sage: T.distorsion_max(3, p=oo)
22/3
sage: T.distorsion_max(4, p=oo)    # long time (4s)
62/17

sage: T = cocycles.Sorted_ARPMulti(3)
sage: T.distorsion_max(1, p=oo)
7
sage: T.distorsion_max(2, p=oo)
9
sage: T.distorsion_max(3, p=oo)
19/2
sage: T.distorsion_max(4, p=oo)  # long time (47s)
161/43

class slabbe.matrix_cocycle.MatrixCocycle(gens, cone=None, language=None)

Bases: object

Matrix cocycle

INPUT:

• gens – list, tuple or dict; the matrices. Keys 0,…,n-1 are used for list and tuple.
• cone – dict or matrix or None (default: None); the cone for each matrix generators. If it is a matrix, then it serves as the cone for all matrices. The cone is defined by the columns of the matrix. If None, then the cone is the identity matrix.
• language – regular language or None (default: None); if None, the language is the full shift.

EXAMPLES:

sage: from slabbe.matrix_cocycle import MatrixCocycle
sage: B1 = matrix(3, [1,0,0, 0,1,0, 0,1,1])
sage: B2 = matrix(3, [1,0,0, 0,0,1, 0,1,1])
sage: B3 = matrix(3, [0,1,0, 0,0,1, 1,0,1])
sage: gens = {'1':B1, '2':B2, '3':B3}
sage: cone = matrix(3, [1,1,1,0,1,1,0,0,1])
sage: MatrixCocycle(gens, cone)
Cocycle with 3 gens over Language of finite words over alphabet ['1', '2', '3']

cone(key)
cone_dict()
distorsion_argmax(n, p=1)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.Sorted_ARP()
sage: ARP.distorsion_argmax(1)
(
[1 0 0]
[1 1 0]
word: A1, [3 2 1]
)

distorsion_max(n, p=1)

EXAMPLES:

Non borné:

sage: from slabbe.matrix_cocycle import cocycles
sage: T = cocycles.Sorted_ARP()
sage: T.distorsion_max(1, p=oo)
1
sage: T.distorsion_max(2, p=oo)
3
sage: T.distorsion_max(3, p=oo)
5
sage: T.distorsion_max(4, p=oo)
7

gens()
gens_inverses()

Return a dictionary of the inverses of the generators.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: coc = cocycles.Brun()
sage: coc.gens_inverses().keys()
[321, 132, 231, 213, 312, 123]
sage: coc.gens_inverses().values()
[
[ 1 -1  0]  [ 1  0  0]  [ 1  0 -1]  [ 1  0  0]  [ 1  0  0]  [ 1  0  0]
[ 0  1  0]  [ 0  1 -1]  [ 0  1  0]  [ 0  1  0]  [-1  1  0]  [ 0  1  0]
[ 0  0  1], [ 0  0  1], [ 0  0  1], [-1  0  1], [ 0  0  1], [ 0 -1  1]
]


If possible, the ring is the Integer ring:

sage: coc = cocycles.Reverse()
sage: coc.gens_inverses().values()
[
[ 1 -1 -1]  [ 1  0  0]  [ 1  0  0]  [-1/2  1/2  1/2]
[ 0  1  0]  [-1  1 -1]  [ 0  1  0]  [ 1/2 -1/2  1/2]
[ 0  0  1], [ 0  0  1], [-1 -1  1], [ 1/2  1/2 -1/2]
]
sage: [m.parent() for m in _]
[Full MatrixSpace of 3 by 3 dense matrices over Integer Ring,
Full MatrixSpace of 3 by 3 dense matrices over Integer Ring,
Full MatrixSpace of 3 by 3 dense matrices over Integer Ring,
Full MatrixSpace of 3 by 3 dense matrices over Rational Field]

identity_matrix()

EXAMPLES:

sage: class Foo:
....:     def __init__(self, x):
....:         self._x = x
....:     @cached_method
....:     def f(self):
....:         return self._x^2
sage: a = Foo(2)
sage: print(a.f.cache)
None
sage: a.f()
4
sage: a.f.cache
4

is_pisot(w)
language()
n_cylinders_edges(n)

Return the set of edges of the n-cylinders.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: ARP.n_cylinders_edges(1)
{frozenset({(1, 1, 0), (1, 1, 1)}),
frozenset({(0, 1, 0), (1, 1, 0)}),
frozenset({(1, 1, 1), (2, 1, 1)}),
frozenset({(0, 0, 1), (1, 0, 1)}),
frozenset({(0, 1, 0), (0, 1, 1)}),
frozenset({(0, 1, 1), (1, 0, 1)}),
frozenset({(1, 0, 0), (1, 1, 0)}),
frozenset({(1, 1, 0), (2, 1, 1)}),
frozenset({(1, 0, 1), (1, 1, 2)}),
frozenset({(1, 1, 0), (1, 2, 1)}),
frozenset({(1, 0, 1), (2, 1, 1)}),
frozenset({(0, 0, 1), (0, 1, 1)}),
frozenset({(1, 0, 1), (1, 1, 1)}),
frozenset({(0, 1, 1), (1, 2, 1)}),
frozenset({(0, 1, 1), (1, 1, 2)}),
frozenset({(1, 0, 0), (1, 0, 1)}),
frozenset({(1, 1, 1), (1, 2, 1)}),
frozenset({(1, 0, 1), (1, 1, 0)}),
frozenset({(0, 1, 1), (1, 1, 1)}),
frozenset({(0, 1, 1), (1, 1, 0)}),
frozenset({(1, 1, 1), (1, 1, 2)})}

n_cylinders_iterator(n)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.ARP()
sage: it = C.n_cylinders_iterator(1)
sage: for w,cyl in it: print("{}\n{}".format(w,cyl))
1
[1 1 1]
[0 1 0]
[0 0 1]
2
[1 0 0]
[1 1 1]
[0 0 1]
3
[1 0 0]
[0 1 0]
[1 1 1]
123
[1 0 1]
[1 1 1]
[1 1 2]
132
[1 1 0]
[1 2 1]
[1 1 1]
213
[1 1 1]
[0 1 1]
[1 1 2]
231
[2 1 1]
[1 1 0]
[1 1 1]
312
[1 1 1]
[1 2 1]
[0 1 1]
321
[2 1 1]
[1 1 1]
[1 0 1]

n_matrices_distorsion_iterator(n, p=1)

Return the the distorsion of the n-cylinders.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: T = cocycles.Sorted_ARP()
sage: it =T.n_matrices_distorsion_iterator(1)
sage: list(it)
[(word: A1, 2),
(word: A2, 2),
(word: A3, 2),
(word: P1, 3),
(word: P2, 3),
(word: P3, 3)]

n_matrices_eigenvalues_iterator(n)

Return the eigenvalues of the matrices of level n.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: list(ARP.n_matrices_eigenvalues_iterator(1))
[(word: 1, [1, 1, 1]),
(word: 2, [1, 1, 1]),
(word: 3, [1, 1, 1]),
(word: 123, [1, 1, 1]),
(word: 132, [1, 1, 1]),
(word: 213, [1, 1, 1]),
(word: 231, [1, 1, 1]),
(word: 312, [1, 1, 1]),
(word: 321, [1, 1, 1])]

sage: B = cocycles.Sorted_Brun()
sage: list(B.n_matrices_eigenvalues_iterator(1))
[(word: 1, [1, 1, 1]),
(word: 2, [1, -0.618033988749895?, 1.618033988749895?]),
(word: 3, [1.465571231876768?,
-0.2327856159383841? - 0.7925519925154479?*I,
-0.2327856159383841? + 0.7925519925154479?*I])]

n_matrices_eigenvectors(n, verbose=False)

Return the left and right eigenvectors of the matrices of level n.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.ARP()
sage: C.n_matrices_eigenvectors(1)
[(word: 1, (1.0, 0.0, 0.0), (0.0, 0.0, 1.0)),
(word: 2, (0.0, 1.0, 0.0), (1.0, 0.0, 0.0)),
(word: 3, (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)),
(word: 123, (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)),
(word: 132, (0.0, 1.0, 0.0), (1.0, 0.0, 0.0)),
(word: 213, (0.0, 0.0, 1.0), (0.0, 1.0, 0.0)),
(word: 231, (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)),
(word: 312, (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)),
(word: 321, (1.0, 0.0, 0.0), (0.0, 0.0, 1.0))]

n_matrices_iterator(n)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.Sorted_ARP()
sage: A,B = zip(*list(ARP.n_matrices_iterator(1)))
sage: A
(word: A1, word: A2, word: A3, word: P1, word: P2, word: P3)
sage: B
(
[1 0 0]  [1 0 0]  [0 1 0]  [0 1 0]  [0 0 1]  [0 0 1]
[0 1 0]  [0 0 1]  [0 0 1]  [0 1 1]  [1 0 1]  [0 1 1]
[1 1 1], [1 1 1], [1 1 1], [1 1 1], [1 1 1], [1 1 1]
)

n_matrices_non_pisot(n, verbose=False)

Return the list of non pisot matrices (as list of indices of base matrices).

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.Sorted_ARP()
sage: ARP.n_matrices_non_pisot(1)
[word: A1, word: A2]
sage: ARP.n_matrices_non_pisot(2)   # long time (1s)
[word: A1,A1, word: A1,A2, word: A2,A1, word: A2,A2]
sage: ARP.n_matrices_non_pisot(3)   # long time (11s)
[word: A1,A1,A1,
word: A1,A1,A2,
word: A1,A2,A1,
word: A1,A2,A2,
word: A2,A1,A1,
word: A2,A1,A2,
word: A2,A2,A1,
word: A2,A2,A2]
sage: len(ARP.n_matrices_non_pisot(4))  # long time
16

sage: from slabbe.matrix_cocycle import cocycles
sage: B = cocycles.Sorted_Brun()
sage: B.n_matrices_non_pisot(2)
[word: 11, word: 12, word: 21, word: 22]
sage: B.n_matrices_non_pisot(3)
[word: 111,
word: 112,
word: 121,
word: 122,
word: 211,
word: 212,
word: 221,
word: 222]

n_matrices_pinching_iterator(n)

Return the pinching matrices of level n.

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: list(ARP.n_matrices_pinching_iterator(0))
[]
sage: list(ARP.n_matrices_pinching_iterator(1))
[]
sage: list(ARP.n_matrices_pinching_iterator(2))
[]
sage: L = list(ARP.n_matrices_pinching_iterator(3))
sage: L[0]
(
[4 5 2]
[2 3 1]
word: 1,2,213, [1 1 1]
)

n_matrices_semi_norm_iterator(n, p=2)

EXAMPLES:

For the 1-norm, all matrices contracts the hyperplane:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.ARP()
sage: it = C.n_matrices_semi_norm_iterator(1, p=1)
sage: for _ in range(5): print(next(it)) # tolerance 0.0001
(word: 1, 1.0, False)
(word: 2, 1.0, False)
(word: 3, 1.0, False)
(word: 123, 0.9999885582839877, False)
(word: 132, 0.9999854006354785, False)


For the 2-norm, AR matrices do not contract:

sage: it = C.n_matrices_semi_norm_iterator(1, p=2)
sage: for w,s,b in it: print(w,s,b)  # long time (6s)
A1 1.30656296488 False
A2 1.30656296486 False
A3 1.30656296475 False
P12 0.99999999996 False
P13 0.999999999967 False
P21 0.999999999967 False
P23 0.999999999997 False
P31 0.999999999769 False
P32 0.999999999839 False


When, the 1-norm is < 1, the product is pisot:

sage: it = C.n_matrices_semi_norm_iterator(2, p=1)
sage: for w,s,b in it: print(w,s,b)  # long time
A1,A1 1.0 False
A1,A2 1.0 False
A1,A3 1.0 False
A1,P12 0.999998922557 False
A1,P13 0.999997464905 False
A1,P21 0.999993244882 False
A1,P23 0.999999150973 True
A1,P31 0.999994030522 False
A1,P32 0.999998046513 True
A2,A1 1.0 False
A2,A2 1.0 False
A2,A3 1.0 False
A2,P12 0.99999375291 False
A2,P13 0.999995591588 True
...
P31,A3 0.999988326888 False
P31,P12 0.749998931902 True
P31,P23 0.799999157344 True
P31,P32 0.749993104833 True
P32,A1 0.999997170005 True
P32,A3 0.99999420509 False
P32,P13 0.666665046248 True
P32,P21 0.666665629351 True
P32,P31 0.666664488371 True

n_words_iterator(n)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.Sorted_ARP()
sage: list(ARP.n_words_iterator(1))
[word: A1, word: A2, word: A3, word: P1, word: P2, word: P3]

non_pisot_automaton(n)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.ARP()
sage: A = C.non_pisot_automaton(2)
sage: A
Automaton with 2 states
sage: A.graph().plot(edge_labels=True)   # not tested

plot_n_cylinders(n, labels=True)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.Sorted_ARP()
sage: G = C.plot_n_cylinders(3)

plot_n_matrices_eigenvectors(n, side='right', color_index=0, draw_line=False)

INPUT:

• n – integer, length
• side'left' or 'right', drawing left or right eigenvectors
• color_index – 0 for first letter, -1 for last letter
• draw_line – boolean

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: G = ARP.plot_n_matrices_eigenvectors(2)

plot_pisot_conjugates(n)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: B = cocycles.Sorted_Brun()
sage: G = B.plot_pisot_conjugates(5)   # long time (8s)


Image envoyee a Timo (6 mai 2014):

sage: G = sum(B.plot_pisot_conjugates(i) for i in [1..6])  #not tested

tikz_n_cylinders(n, labels=None, scale=1)

INPUT:

• n – integer, for the nth-cylinders
• labels – None, True or False (default: None), if None, it takes value True if n is 1.
• scale – real (default: 1), scale value for tikzpicture

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: ARP = cocycles.ARP()
sage: t = ARP.tikz_n_cylinders(1, labels=True, scale=4)
sage: t
\documentclass[tikz]{standalone}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}
[scale=4]
\draw (0.0000, -0.5000) -- (0.0000, 0.0000);
\draw (0.0000, -0.5000) -- (0.8660, -0.5000);
\draw (0.0000, 0.0000) -- (-0.2165, -0.1250);
...
... 23 lines not printed (1317 characters in total) ...
...
\node at (-0.1443, 0.1667) {$213$};
\node at (-0.2165, 0.0417) {$231$};
\node at (0.0722, -0.2083) {$312$};
\node at (-0.0722, -0.2083) {$321$};
\end{tikzpicture}
\end{document}

sage: from sage.misc.temporary_file import tmp_filename
sage: filename = tmp_filename('temp','.pdf')
sage: _ = t.pdf(filename)

word_to_matrix(w)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.Sorted_ARP()
sage: C.word_to_matrix(Word())
[1 0 0]
[0 1 0]
[0 0 1]

class slabbe.matrix_cocycle.MatrixCocycleGenerator

Bases: object

ARP()
ArnouxRauzy()
Brun()
Cassaigne()

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: c = cocycles.Cassaigne()
sage: list(m for (w,m) in c.n_cylinders_iterator(2))
[
[1 1 1]  [1 1 0]  [0 0 1]  [1 0 0]
[0 1 0]  [0 1 1]  [1 1 0]  [0 1 0]
[0 0 1], [1 0 0], [0 1 1], [1 1 1]
]

Cassaigne_accelerated(order=3)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cocycles
sage: c = cocycles.Cassaigne_accelerated(order=3)
sage: c
Cocycle with 6 gens over Language of finite words over
alphabet ['11', '121', '12^{2}1', '212', '21^{2}2', '22']

FullySubtractive()
Poincare()
Reverse()
Selmer()
Sorted_ARP()
Sorted_ARPMulti(order=3)
Sorted_Brun()
slabbe.matrix_cocycle.arp_polyhedron(d=3)

Return the d-dimensional 1-cylinders of the ARP algorithm.

EXAMPLES:

sage: from slabbe.matrix_cocycle import arp_polyhedron
sage: A,P,L = arp_polyhedron(3)
sage: A.vertices_list()
[[0, 0, 0], [1/2, 1/2, 0], [1/2, 1/4, 1/4], [1, 0, 0]]
sage: P.vertices_list()
[[0, 0, 0], [1/2, 1/2, 0], [1/2, 1/4, 1/4], [1/3, 1/3, 1/3]]

sage: A,P,L = arp_polyhedron(4)
sage: A.vertices_list()
[[0, 0, 0, 0],
[1/2, 1/2, 0, 0],
[1/2, 1/6, 1/6, 1/6],
[1/2, 1/4, 1/4, 0],
[1, 0, 0, 0]]
sage: P.vertices_list()
[[0, 0, 0, 0],
[1/2, 1/2, 0, 0],
[1/2, 1/4, 1/4, 0],
[1/2, 1/6, 1/6, 1/6],
[1/4, 1/4, 1/4, 1/4],
[1/3, 1/3, 1/3, 0]]

sage: A,P,L = arp_polyhedron(5)
sage: A.vertices_list()
[[0, 0, 0, 0, 0],
[1/2, 1/2, 0, 0, 0],
[1/2, 1/8, 1/8, 1/8, 1/8],
[1/2, 1/6, 1/6, 1/6, 0],
[1/2, 1/4, 1/4, 0, 0],
[1, 0, 0, 0, 0]]
sage: P.vertices_list()
[[0, 0, 0, 0, 0],
[1/2, 1/2, 0, 0, 0],
[1/2, 1/6, 1/6, 1/6, 0],
[1/2, 1/8, 1/8, 1/8, 1/8],
[1/2, 1/4, 1/4, 0, 0],
[1/3, 1/3, 1/3, 0, 0],
[1/5, 1/5, 1/5, 1/5, 1/5],
[1/4, 1/4, 1/4, 1/4, 0]]

slabbe.matrix_cocycle.cassaigne_polyhedron(d=3)

Return the d-dimensional 1-cylinders of the Cassaigne algorithm.

(of the dual!)

EXAMPLES:

sage: from slabbe.matrix_cocycle import cassaigne_polyhedron
sage: L,La,Lb = cassaigne_polyhedron(3)
sage: L.vertices_list()
[[0, 0, 0], [0, 1/2, 1/2], [1/3, 1/3, 1/3], [1/2, 1/2, 0]]
sage: La.vertices_list()
[[0, 0, 0], [0, 1/2, 1/2], [1/3, 1/3, 1/3], [1/4, 1/2, 1/4]]
sage: Lb.vertices_list()
[[0, 0, 0], [1/3, 1/3, 1/3], [1/2, 1/2, 0], [1/4, 1/2, 1/4]]

sage: L,La,Lb = cassaigne_polyhedron(4)
sage: L.vertices_list()
[[0, 0, 0, 0],
[0, 1/3, 1/3, 1/3],
[1/3, 1/3, 1/3, 0],
[1/4, 1/4, 1/4, 1/4],
[1/5, 2/5, 1/5, 1/5],
[1/5, 1/5, 2/5, 1/5]]

sage: L,La,Lb = cassaigne_polyhedron(5)
sage: L.vertices_list()
[[0, 0, 0, 0, 0],
[0, 1/4, 1/4, 1/4, 1/4],
[1/4, 1/4, 1/4, 1/4, 0],
[1/6, 1/6, 1/3, 1/6, 1/6],
[1/5, 1/5, 1/5, 1/5, 1/5],
[1/6, 1/3, 1/6, 1/6, 1/6],
[1/7, 2/7, 2/7, 1/7, 1/7],
[1/7, 2/7, 1/7, 2/7, 1/7],
[1/7, 1/7, 2/7, 2/7, 1/7],
[1/6, 1/6, 1/6, 1/3, 1/6]]

slabbe.matrix_cocycle.distorsion(M, p=1)

1 Avril 2014. L’ancien ratio n’était pas le bon. Je n’utilisais pas les bonnes normes.

EXAMPLES:

sage: from slabbe.matrix_cocycle import distorsion
sage: M = matrix(3, (1,2,3,4,5,6,7,8,9))
sage: M
[1 2 3]
[4 5 6]
[7 8 9]
sage: distorsion(M)
3/2
sage: (3+6+9) / (1+4+7)
3/2
sage: distorsion(M, p=oo)
9/7

slabbe.matrix_cocycle.is_pisot(m)

EXAMPLES:

sage: from slabbe.matrix_cocycle import is_pisot
sage: M = matrix(3, (1,2,3,4,5,6,7,8,9))
sage: is_pisot(M)
False

slabbe.matrix_cocycle.perron_right_eigenvector(M)

EXAMPLES:

sage: from slabbe.matrix_cocycle import perron_right_eigenvector
sage: m = matrix(2,[-11,14,-26,29])
sage: perron_right_eigenvector(m)           # tolerance 0.00001
(15.0000000000000, (0.35, 0.6499999999999999))

slabbe.matrix_cocycle.rounded_string_vector(v, digits=4)

EXAMPLES:

sage: from slabbe.matrix_cocycle import rounded_string_vector
sage: v = (-0.144337567297406, 0.166666666666667)
sage: rounded_string_vector(v)
'(-0.1443, 0.1667)'
sage: rounded_string_vector(v, digits=6)
'(-0.144338, 0.166667)'

slabbe.matrix_cocycle.semi_norm_D(v)

EXAMPLES:

sage: from slabbe.matrix_cocycle import semi_norm_D
sage: semi_norm_D((1,2,3,-5))
8

slabbe.matrix_cocycle.semi_norm_cone(M, cone, p=2, verbose=False)

Return the semi norm on the hyperplane orthogonal to v where v lives in the cone.

EXAMPLES:

For Arnoux-Rauzy, only the 1-norm works:

sage: from slabbe.matrix_cocycle import semi_norm_cone
sage: A1 = matrix(3, [1,1,1, 0,1,0, 0,0,1])
sage: cone = A1
sage: semi_norm_cone(A1.transpose(), cone, p=1)    # tolerance 0.00001
0.9999999999999998
sage: semi_norm_cone(A1.transpose(), cone, p=oo)   # tolerance 0.0001
1.9999757223144654
sage: semi_norm_cone(A1.transpose(), cone, p=2)   # tolerance 0.00001
1.3065629648763757


For Poincaré, all norms work:

sage: P21 = matrix(3, [1,1,1, 0,1,1, 0,0,1])
sage: H21 = matrix(3, [1,0,0, 0,1,0, 1,0,1])
sage: cone = P21 * H21
sage: semi_norm_cone(P21.transpose(), cone, p=1)   # tolerance 0.00001
0.9999957276014074
sage: semi_norm_cone(P21.transpose(), cone, p=oo)   # tolerance 0.00001
1.0
sage: semi_norm_cone(P21.transpose(), cone, p=2)   # tolerance 0.00001
0.9999999999670175


For Poincaré on the whole cone, it works for some norms:

sage: P21 = matrix(3, [1,1,1, 0,1,1, 0,0,1])
sage: cone = P21
sage: semi_norm_cone(P21.transpose(), cone, p=1)   # tolerance 0.0001 # known bug
1.9999675644077723
sage: semi_norm_cone(P21.transpose(), cone, p=2)   # tolerance 0.00001
1.6180339887021953
sage: semi_norm_cone(P21.transpose(), cone, p=oo)   # tolerance 0.00001
1.0


For a product, all norms work:

sage: A1 = matrix(3, [1,1,1, 0,1,0, 0,0,1])
sage: P21 = matrix(3, [1,1,1, 0,1,1, 0,0,1])
sage: H21 = matrix(3, [1,0,0, 0,1,0, 1,0,1])
sage: M = A1 * P21
sage: cone = A1 * P21 * H21
sage: semi_norm_cone(M.transpose(), cone, p=1)   # tolerance 0.00001
0.999993244882415
sage: semi_norm_cone(M.transpose(), cone, p=oo)   # tolerance 0.00001
0.9999935206958908
sage: semi_norm_cone(M.transpose(), cone, p=2)   # tolerance 0.00001
0.7529377601317161

sage: M = cone = matrix(3,[2,3,2, 2,2,1, 1,2,1])
sage: semi_norm_cone(M.T, cone, p='D')  # tolerance 0.00001
0.7499977852638109

slabbe.matrix_cocycle.semi_norm_v(M, v, p=2, verbose=False)

Return the semi norm on the hyperplane orthogonal to v.

EXAMPLES:

sage: from slabbe.matrix_cocycle import semi_norm_v
sage: A1 = matrix(3, [1,-1,-1, 0,1,0, 0,0,1]).inverse()
sage: semi_norm_v(A1, vector( (1,1,1)))[0]      # tolerance 0.0001
0.9999999999890247
sage: semi_norm_v(A1, vector( (1,1,1)), p=1)[0]   # tolerance 0.0001
0.9999394820959548
sage: semi_norm_v(A1, vector( (1,1,1)), p=oo)[0]   # tolerance 0.0001
1.0

sage: m = matrix(3,[0,0,0, 1,0,1, 0,-1,0])
sage: semi_norm_v(m, vector((1,1,1)), p='D')[0]  # tolerance 0.0001
0.6666436827952827