# 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: list(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)
53/7
```
```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) # not tested
126/13
```
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
```
first_postive_automaton(n)

EXAMPLES:

```sage: from slabbe.matrix_cocycle import cocycles
sage: C = cocycles.Cassaigne()
sage: A = C.first_postive_automaton(7)
sage: A
Automaton with 21 states
sage: A.graph().plot(edge_labels=True)   # not tested
```
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: sorted(coc.gens_inverses().keys())
[123, 132, 213, 231, 312, 321]
sage: sorted(coc.gens_inverses().values())
[
[ 1 -1  0]  [ 1  0 -1]  [ 1  0  0]  [ 1  0  0]  [ 1  0  0]  [ 1  0  0]
[ 0  1  0]  [ 0  1  0]  [-1  1  0]  [ 0  1 -1]  [ 0  1  0]  [ 0  1  0]
[ 0  0  1], [ 0  0  1], [ 0  0  1], [ 0  0  1], [-1  0  1], [ 0 -1  1]
]
```

If possible, the ring is the Integer ring:

```sage: coc = cocycles.Reverse()
sage: sorted(coc.gens_inverses().values())
[
[-1/2  1/2  1/2]  [ 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]
]
sage: [m.parent() for m in _]
[Full MatrixSpace of 3 by 3 dense matrices over Rational Field,
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]
```
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: len(ARP.n_cylinders_edges(1))
21
```
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 (6s)
[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 (22s) # not tested
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)) # long time (1s) # 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) # tolerance 0.0001
1 1.30656296488 False
2 1.30656296486 False
3 1.30656296475 False
123 0.99999999996 False
132 0.999999999967 False
213 0.999999999967 False
231 0.999999999997 False
312 0.999999999769 False
321 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 # not tested
11 1.0 False
12 1.0 False
13 1.0000000000000002 False
1,123 0.9999968942506897 True
1,132 0.9999987894422356 True
1,213 0.9999964086309794 False
1,231 0.9999899345706303 False
1,312 0.9999985339769911 False
1,321 0.9999932100052813 False
21 1.0 False
22 1.0000000000000002 False
23 0.9999999999999998 False
2,123 0.9999976016405222 False
2,132 0.9999871840192867 False
...
231,312 0.7499985368044536 True
312,1 0.9999929100695556 False
312,3 0.9999924874380424 True
312,123 0.6666658877702296 True
312,213 0.7499990158628145 True
312,231 0.5999954614129098 True
321,2 0.9999940879276639 False
321,3 0.9999930338943775 True
321,123 0.7499989002141297 True
321,132 0.5999961806665235 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(2)
sage: G = B.plot_pisot_conjugates(5)  # long time (8s) # not tested
```

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]
...
... 23 lines not printed (1317 characters in total) ...
...
\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
```