```python
from sympy import *
```

```python
p= 5
s = 2
n = p**s + 1
```

```python
print n
```

    26

```python
values = {}
values[1] = [symbols('x_{}'.format(i)) for i in range(1, n + 1)]
```

```python
values
```

    {1: [x_1,
      x_2,
      x_3,
      x_4,
      x_5,
      x_6,
      x_7,
      x_8,
      x_9,
      x_10,
      x_11,
      x_12,
      x_13,
      x_14,
      x_15,
      x_16,
      x_17,
      x_18,
      x_19,
      x_20,
      x_21,
      x_22,
      x_23,
      x_24,
      x_25,
      x_26]}

```python
for i in range(2, n + 1):
    values[i] = [p - values[i - 1][j] + p - values[i - 1][j + 1] for j in range(0, n - i + 1)]
```

```python
values
```

    {1: [x_1,
      x_2,
      x_3,
      x_4,
      x_5,
      x_6,
      x_7,
      x_8,
      x_9,
      x_10,
      x_11,
      x_12,
      x_13,
      x_14,
      x_15,
      x_16,
      x_17,
      x_18,
      x_19,
      x_20,
      x_21,
      x_22,
      x_23,
      x_24,
      x_25,
      x_26],
     2: [-x_1 - x_2 + 10,
      -x_2 - x_3 + 10,
      -x_3 - x_4 + 10,
      -x_4 - x_5 + 10,
      -x_5 - x_6 + 10,
      -x_6 - x_7 + 10,
      -x_7 - x_8 + 10,
      -x_8 - x_9 + 10,
      -x_10 - x_9 + 10,
      -x_10 - x_11 + 10,
      -x_11 - x_12 + 10,
      -x_12 - x_13 + 10,
      -x_13 - x_14 + 10,
      -x_14 - x_15 + 10,
      -x_15 - x_16 + 10,
      -x_16 - x_17 + 10,
      -x_17 - x_18 + 10,
      -x_18 - x_19 + 10,
      -x_19 - x_20 + 10,
      -x_20 - x_21 + 10,
      -x_21 - x_22 + 10,
      -x_22 - x_23 + 10,
      -x_23 - x_24 + 10,
      -x_24 - x_25 + 10,
      -x_25 - x_26 + 10],
     3: [x_1 + 2*x_2 + x_3 - 10,
      x_2 + 2*x_3 + x_4 - 10,
      x_3 + 2*x_4 + x_5 - 10,
      x_4 + 2*x_5 + x_6 - 10,
      x_5 + 2*x_6 + x_7 - 10,
      x_6 + 2*x_7 + x_8 - 10,
      x_7 + 2*x_8 + x_9 - 10,
      x_10 + x_8 + 2*x_9 - 10,
      2*x_10 + x_11 + x_9 - 10,
      x_10 + 2*x_11 + x_12 - 10,
      x_11 + 2*x_12 + x_13 - 10,
      x_12 + 2*x_13 + x_14 - 10,
      x_13 + 2*x_14 + x_15 - 10,
      x_14 + 2*x_15 + x_16 - 10,
      x_15 + 2*x_16 + x_17 - 10,
      x_16 + 2*x_17 + x_18 - 10,
      x_17 + 2*x_18 + x_19 - 10,
      x_18 + 2*x_19 + x_20 - 10,
      x_19 + 2*x_20 + x_21 - 10,
      x_20 + 2*x_21 + x_22 - 10,
      x_21 + 2*x_22 + x_23 - 10,
      x_22 + 2*x_23 + x_24 - 10,
      x_23 + 2*x_24 + x_25 - 10,
      x_24 + 2*x_25 + x_26 - 10],
     4: [-x_1 - 3*x_2 - 3*x_3 - x_4 + 30,
      -x_2 - 3*x_3 - 3*x_4 - x_5 + 30,
      -x_3 - 3*x_4 - 3*x_5 - x_6 + 30,
      -x_4 - 3*x_5 - 3*x_6 - x_7 + 30,
      -x_5 - 3*x_6 - 3*x_7 - x_8 + 30,
      -x_6 - 3*x_7 - 3*x_8 - x_9 + 30,
      -x_10 - x_7 - 3*x_8 - 3*x_9 + 30,
      -3*x_10 - x_11 - x_8 - 3*x_9 + 30,
      -3*x_10 - 3*x_11 - x_12 - x_9 + 30,
      -x_10 - 3*x_11 - 3*x_12 - x_13 + 30,
      -x_11 - 3*x_12 - 3*x_13 - x_14 + 30,
      -x_12 - 3*x_13 - 3*x_14 - x_15 + 30,
      -x_13 - 3*x_14 - 3*x_15 - x_16 + 30,
      -x_14 - 3*x_15 - 3*x_16 - x_17 + 30,
      -x_15 - 3*x_16 - 3*x_17 - x_18 + 30,
      -x_16 - 3*x_17 - 3*x_18 - x_19 + 30,
      -x_17 - 3*x_18 - 3*x_19 - x_20 + 30,
      -x_18 - 3*x_19 - 3*x_20 - x_21 + 30,
      -x_19 - 3*x_20 - 3*x_21 - x_22 + 30,
      -x_20 - 3*x_21 - 3*x_22 - x_23 + 30,
      -x_21 - 3*x_22 - 3*x_23 - x_24 + 30,
      -x_22 - 3*x_23 - 3*x_24 - x_25 + 30,
      -x_23 - 3*x_24 - 3*x_25 - x_26 + 30],
     5: [x_1 + 4*x_2 + 6*x_3 + 4*x_4 + x_5 - 50,
      x_2 + 4*x_3 + 6*x_4 + 4*x_5 + x_6 - 50,
      x_3 + 4*x_4 + 6*x_5 + 4*x_6 + x_7 - 50,
      x_4 + 4*x_5 + 6*x_6 + 4*x_7 + x_8 - 50,
      x_5 + 4*x_6 + 6*x_7 + 4*x_8 + x_9 - 50,
      x_10 + x_6 + 4*x_7 + 6*x_8 + 4*x_9 - 50,
      4*x_10 + x_11 + x_7 + 4*x_8 + 6*x_9 - 50,
      6*x_10 + 4*x_11 + x_12 + x_8 + 4*x_9 - 50,
      4*x_10 + 6*x_11 + 4*x_12 + x_13 + x_9 - 50,
      x_10 + 4*x_11 + 6*x_12 + 4*x_13 + x_14 - 50,
      x_11 + 4*x_12 + 6*x_13 + 4*x_14 + x_15 - 50,
      x_12 + 4*x_13 + 6*x_14 + 4*x_15 + x_16 - 50,
      x_13 + 4*x_14 + 6*x_15 + 4*x_16 + x_17 - 50,
      x_14 + 4*x_15 + 6*x_16 + 4*x_17 + x_18 - 50,
      x_15 + 4*x_16 + 6*x_17 + 4*x_18 + x_19 - 50,
      x_16 + 4*x_17 + 6*x_18 + 4*x_19 + x_20 - 50,
      x_17 + 4*x_18 + 6*x_19 + 4*x_20 + x_21 - 50,
      x_18 + 4*x_19 + 6*x_20 + 4*x_21 + x_22 - 50,
      x_19 + 4*x_20 + 6*x_21 + 4*x_22 + x_23 - 50,
      x_20 + 4*x_21 + 6*x_22 + 4*x_23 + x_24 - 50,
      x_21 + 4*x_22 + 6*x_23 + 4*x_24 + x_25 - 50,
      x_22 + 4*x_23 + 6*x_24 + 4*x_25 + x_26 - 50],
     6: [-x_1 - 5*x_2 - 10*x_3 - 10*x_4 - 5*x_5 - x_6 + 110,
      -x_2 - 5*x_3 - 10*x_4 - 10*x_5 - 5*x_6 - x_7 + 110,
      -x_3 - 5*x_4 - 10*x_5 - 10*x_6 - 5*x_7 - x_8 + 110,
      -x_4 - 5*x_5 - 10*x_6 - 10*x_7 - 5*x_8 - x_9 + 110,
      -x_10 - x_5 - 5*x_6 - 10*x_7 - 10*x_8 - 5*x_9 + 110,
      -5*x_10 - x_11 - x_6 - 5*x_7 - 10*x_8 - 10*x_9 + 110,
      -10*x_10 - 5*x_11 - x_12 - x_7 - 5*x_8 - 10*x_9 + 110,
      -10*x_10 - 10*x_11 - 5*x_12 - x_13 - x_8 - 5*x_9 + 110,
      -5*x_10 - 10*x_11 - 10*x_12 - 5*x_13 - x_14 - x_9 + 110,
      -x_10 - 5*x_11 - 10*x_12 - 10*x_13 - 5*x_14 - x_15 + 110,
      -x_11 - 5*x_12 - 10*x_13 - 10*x_14 - 5*x_15 - x_16 + 110,
      -x_12 - 5*x_13 - 10*x_14 - 10*x_15 - 5*x_16 - x_17 + 110,
      -x_13 - 5*x_14 - 10*x_15 - 10*x_16 - 5*x_17 - x_18 + 110,
      -x_14 - 5*x_15 - 10*x_16 - 10*x_17 - 5*x_18 - x_19 + 110,
      -x_15 - 5*x_16 - 10*x_17 - 10*x_18 - 5*x_19 - x_20 + 110,
      -x_16 - 5*x_17 - 10*x_18 - 10*x_19 - 5*x_20 - x_21 + 110,
      -x_17 - 5*x_18 - 10*x_19 - 10*x_20 - 5*x_21 - x_22 + 110,
      -x_18 - 5*x_19 - 10*x_20 - 10*x_21 - 5*x_22 - x_23 + 110,
      -x_19 - 5*x_20 - 10*x_21 - 10*x_22 - 5*x_23 - x_24 + 110,
      -x_20 - 5*x_21 - 10*x_22 - 10*x_23 - 5*x_24 - x_25 + 110,
      -x_21 - 5*x_22 - 10*x_23 - 10*x_24 - 5*x_25 - x_26 + 110],
     7: [x_1 + 6*x_2 + 15*x_3 + 20*x_4 + 15*x_5 + 6*x_6 + x_7 - 210,
      x_2 + 6*x_3 + 15*x_4 + 20*x_5 + 15*x_6 + 6*x_7 + x_8 - 210,
      x_3 + 6*x_4 + 15*x_5 + 20*x_6 + 15*x_7 + 6*x_8 + x_9 - 210,
      x_10 + x_4 + 6*x_5 + 15*x_6 + 20*x_7 + 15*x_8 + 6*x_9 - 210,
      6*x_10 + x_11 + x_5 + 6*x_6 + 15*x_7 + 20*x_8 + 15*x_9 - 210,
      15*x_10 + 6*x_11 + x_12 + x_6 + 6*x_7 + 15*x_8 + 20*x_9 - 210,
      20*x_10 + 15*x_11 + 6*x_12 + x_13 + x_7 + 6*x_8 + 15*x_9 - 210,
      15*x_10 + 20*x_11 + 15*x_12 + 6*x_13 + x_14 + x_8 + 6*x_9 - 210,
      6*x_10 + 15*x_11 + 20*x_12 + 15*x_13 + 6*x_14 + x_15 + x_9 - 210,
      x_10 + 6*x_11 + 15*x_12 + 20*x_13 + 15*x_14 + 6*x_15 + x_16 - 210,
      x_11 + 6*x_12 + 15*x_13 + 20*x_14 + 15*x_15 + 6*x_16 + x_17 - 210,
      x_12 + 6*x_13 + 15*x_14 + 20*x_15 + 15*x_16 + 6*x_17 + x_18 - 210,
      x_13 + 6*x_14 + 15*x_15 + 20*x_16 + 15*x_17 + 6*x_18 + x_19 - 210,
      x_14 + 6*x_15 + 15*x_16 + 20*x_17 + 15*x_18 + 6*x_19 + x_20 - 210,
      x_15 + 6*x_16 + 15*x_17 + 20*x_18 + 15*x_19 + 6*x_20 + x_21 - 210,
      x_16 + 6*x_17 + 15*x_18 + 20*x_19 + 15*x_20 + 6*x_21 + x_22 - 210,
      x_17 + 6*x_18 + 15*x_19 + 20*x_20 + 15*x_21 + 6*x_22 + x_23 - 210,
      x_18 + 6*x_19 + 15*x_20 + 20*x_21 + 15*x_22 + 6*x_23 + x_24 - 210,
      x_19 + 6*x_20 + 15*x_21 + 20*x_22 + 15*x_23 + 6*x_24 + x_25 - 210,
      x_20 + 6*x_21 + 15*x_22 + 20*x_23 + 15*x_24 + 6*x_25 + x_26 - 210],
     8: [-x_1 - 7*x_2 - 21*x_3 - 35*x_4 - 35*x_5 - 21*x_6 - 7*x_7 - x_8 + 430,
      -x_2 - 7*x_3 - 21*x_4 - 35*x_5 - 35*x_6 - 21*x_7 - 7*x_8 - x_9 + 430,
      -x_10 - x_3 - 7*x_4 - 21*x_5 - 35*x_6 - 35*x_7 - 21*x_8 - 7*x_9 + 430,
      -7*x_10 - x_11 - x_4 - 7*x_5 - 21*x_6 - 35*x_7 - 35*x_8 - 21*x_9 + 430,
      -21*x_10 - 7*x_11 - x_12 - x_5 - 7*x_6 - 21*x_7 - 35*x_8 - 35*x_9 + 430,
      -35*x_10 - 21*x_11 - 7*x_12 - x_13 - x_6 - 7*x_7 - 21*x_8 - 35*x_9 + 430,
      -35*x_10 - 35*x_11 - 21*x_12 - 7*x_13 - x_14 - x_7 - 7*x_8 - 21*x_9 + 430,
      -21*x_10 - 35*x_11 - 35*x_12 - 21*x_13 - 7*x_14 - x_15 - x_8 - 7*x_9 + 430,
      -7*x_10 - 21*x_11 - 35*x_12 - 35*x_13 - 21*x_14 - 7*x_15 - x_16 - x_9 + 430,
      -x_10 - 7*x_11 - 21*x_12 - 35*x_13 - 35*x_14 - 21*x_15 - 7*x_16 - x_17 + 430,
      -x_11 - 7*x_12 - 21*x_13 - 35*x_14 - 35*x_15 - 21*x_16 - 7*x_17 - x_18 + 430,
      -x_12 - 7*x_13 - 21*x_14 - 35*x_15 - 35*x_16 - 21*x_17 - 7*x_18 - x_19 + 430,
      -x_13 - 7*x_14 - 21*x_15 - 35*x_16 - 35*x_17 - 21*x_18 - 7*x_19 - x_20 + 430,
      -x_14 - 7*x_15 - 21*x_16 - 35*x_17 - 35*x_18 - 21*x_19 - 7*x_20 - x_21 + 430,
      -x_15 - 7*x_16 - 21*x_17 - 35*x_18 - 35*x_19 - 21*x_20 - 7*x_21 - x_22 + 430,
      -x_16 - 7*x_17 - 21*x_18 - 35*x_19 - 35*x_20 - 21*x_21 - 7*x_22 - x_23 + 430,
      -x_17 - 7*x_18 - 21*x_19 - 35*x_20 - 35*x_21 - 21*x_22 - 7*x_23 - x_24 + 430,
      -x_18 - 7*x_19 - 21*x_20 - 35*x_21 - 35*x_22 - 21*x_23 - 7*x_24 - x_25 + 430,
      -x_19 - 7*x_20 - 21*x_21 - 35*x_22 - 35*x_23 - 21*x_24 - 7*x_25 - x_26 + 430],
     9: [x_1 + 8*x_2 + 28*x_3 + 56*x_4 + 70*x_5 + 56*x_6 + 28*x_7 + 8*x_8 + x_9 - 850,
      x_10 + x_2 + 8*x_3 + 28*x_4 + 56*x_5 + 70*x_6 + 56*x_7 + 28*x_8 + 8*x_9 - 850,
      8*x_10 + x_11 + x_3 + 8*x_4 + 28*x_5 + 56*x_6 + 70*x_7 + 56*x_8 + 28*x_9 - 850,
      28*x_10 + 8*x_11 + x_12 + x_4 + 8*x_5 + 28*x_6 + 56*x_7 + 70*x_8 + 56*x_9 - 850,
      56*x_10 + 28*x_11 + 8*x_12 + x_13 + x_5 + 8*x_6 + 28*x_7 + 56*x_8 + 70*x_9 - 850,
      70*x_10 + 56*x_11 + 28*x_12 + 8*x_13 + x_14 + x_6 + 8*x_7 + 28*x_8 + 56*x_9 - 850,
      56*x_10 + 70*x_11 + 56*x_12 + 28*x_13 + 8*x_14 + x_15 + x_7 + 8*x_8 + 28*x_9 - 850,
      28*x_10 + 56*x_11 + 70*x_12 + 56*x_13 + 28*x_14 + 8*x_15 + x_16 + x_8 + 8*x_9 - 850,
      8*x_10 + 28*x_11 + 56*x_12 + 70*x_13 + 56*x_14 + 28*x_15 + 8*x_16 + x_17 + x_9 - 850,
      x_10 + 8*x_11 + 28*x_12 + 56*x_13 + 70*x_14 + 56*x_15 + 28*x_16 + 8*x_17 + x_18 - 850,
      x_11 + 8*x_12 + 28*x_13 + 56*x_14 + 70*x_15 + 56*x_16 + 28*x_17 + 8*x_18 + x_19 - 850,
      x_12 + 8*x_13 + 28*x_14 + 56*x_15 + 70*x_16 + 56*x_17 + 28*x_18 + 8*x_19 + x_20 - 850,
      x_13 + 8*x_14 + 28*x_15 + 56*x_16 + 70*x_17 + 56*x_18 + 28*x_19 + 8*x_20 + x_21 - 850,
      x_14 + 8*x_15 + 28*x_16 + 56*x_17 + 70*x_18 + 56*x_19 + 28*x_20 + 8*x_21 + x_22 - 850,
      x_15 + 8*x_16 + 28*x_17 + 56*x_18 + 70*x_19 + 56*x_20 + 28*x_21 + 8*x_22 + x_23 - 850,
      x_16 + 8*x_17 + 28*x_18 + 56*x_19 + 70*x_20 + 56*x_21 + 28*x_22 + 8*x_23 + x_24 - 850,
      x_17 + 8*x_18 + 28*x_19 + 56*x_20 + 70*x_21 + 56*x_22 + 28*x_23 + 8*x_24 + x_25 - 850,
      x_18 + 8*x_19 + 28*x_20 + 56*x_21 + 70*x_22 + 56*x_23 + 28*x_24 + 8*x_25 + x_26 - 850],
     10: [-x_1 - x_10 - 9*x_2 - 36*x_3 - 84*x_4 - 126*x_5 - 126*x_6 - 84*x_7 - 36*x_8 - 9*x_9 + 1710,
      -9*x_10 - x_11 - x_2 - 9*x_3 - 36*x_4 - 84*x_5 - 126*x_6 - 126*x_7 - 84*x_8 - 36*x_9 + 1710,
      -36*x_10 - 9*x_11 - x_12 - x_3 - 9*x_4 - 36*x_5 - 84*x_6 - 126*x_7 - 126*x_8 - 84*x_9 + 1710,
      -84*x_10 - 36*x_11 - 9*x_12 - x_13 - x_4 - 9*x_5 - 36*x_6 - 84*x_7 - 126*x_8 - 126*x_9 + 1710,
      -126*x_10 - 84*x_11 - 36*x_12 - 9*x_13 - x_14 - x_5 - 9*x_6 - 36*x_7 - 84*x_8 - 126*x_9 + 1710,
      -126*x_10 - 126*x_11 - 84*x_12 - 36*x_13 - 9*x_14 - x_15 - x_6 - 9*x_7 - 36*x_8 - 84*x_9 + 1710,
      -84*x_10 - 126*x_11 - 126*x_12 - 84*x_13 - 36*x_14 - 9*x_15 - x_16 - x_7 - 9*x_8 - 36*x_9 + 1710,
      -36*x_10 - 84*x_11 - 126*x_12 - 126*x_13 - 84*x_14 - 36*x_15 - 9*x_16 - x_17 - x_8 - 9*x_9 + 1710,
      -9*x_10 - 36*x_11 - 84*x_12 - 126*x_13 - 126*x_14 - 84*x_15 - 36*x_16 - 9*x_17 - x_18 - x_9 + 1710,
      -x_10 - 9*x_11 - 36*x_12 - 84*x_13 - 126*x_14 - 126*x_15 - 84*x_16 - 36*x_17 - 9*x_18 - x_19 + 1710,
      -x_11 - 9*x_12 - 36*x_13 - 84*x_14 - 126*x_15 - 126*x_16 - 84*x_17 - 36*x_18 - 9*x_19 - x_20 + 1710,
      -x_12 - 9*x_13 - 36*x_14 - 84*x_15 - 126*x_16 - 126*x_17 - 84*x_18 - 36*x_19 - 9*x_20 - x_21 + 1710,
      -x_13 - 9*x_14 - 36*x_15 - 84*x_16 - 126*x_17 - 126*x_18 - 84*x_19 - 36*x_20 - 9*x_21 - x_22 + 1710,
      -x_14 - 9*x_15 - 36*x_16 - 84*x_17 - 126*x_18 - 126*x_19 - 84*x_20 - 36*x_21 - 9*x_22 - x_23 + 1710,
      -x_15 - 9*x_16 - 36*x_17 - 84*x_18 - 126*x_19 - 126*x_20 - 84*x_21 - 36*x_22 - 9*x_23 - x_24 + 1710,
      -x_16 - 9*x_17 - 36*x_18 - 84*x_19 - 126*x_20 - 126*x_21 - 84*x_22 - 36*x_23 - 9*x_24 - x_25 + 1710,
      -x_17 - 9*x_18 - 36*x_19 - 84*x_20 - 126*x_21 - 126*x_22 - 84*x_23 - 36*x_24 - 9*x_25 - x_26 + 1710],
     11: [x_1 + 10*x_10 + x_11 + 10*x_2 + 45*x_3 + 120*x_4 + 210*x_5 + 252*x_6 + 210*x_7 + 120*x_8 + 45*x_9 - 3410,
      45*x_10 + 10*x_11 + x_12 + x_2 + 10*x_3 + 45*x_4 + 120*x_5 + 210*x_6 + 252*x_7 + 210*x_8 + 120*x_9 - 3410,
      120*x_10 + 45*x_11 + 10*x_12 + x_13 + x_3 + 10*x_4 + 45*x_5 + 120*x_6 + 210*x_7 + 252*x_8 + 210*x_9 - 3410,
      210*x_10 + 120*x_11 + 45*x_12 + 10*x_13 + x_14 + x_4 + 10*x_5 + 45*x_6 + 120*x_7 + 210*x_8 + 252*x_9 - 3410,
      252*x_10 + 210*x_11 + 120*x_12 + 45*x_13 + 10*x_14 + x_15 + x_5 + 10*x_6 + 45*x_7 + 120*x_8 + 210*x_9 - 3410,
      210*x_10 + 252*x_11 + 210*x_12 + 120*x_13 + 45*x_14 + 10*x_15 + x_16 + x_6 + 10*x_7 + 45*x_8 + 120*x_9 - 3410,
      120*x_10 + 210*x_11 + 252*x_12 + 210*x_13 + 120*x_14 + 45*x_15 + 10*x_16 + x_17 + x_7 + 10*x_8 + 45*x_9 - 3410,
      45*x_10 + 120*x_11 + 210*x_12 + 252*x_13 + 210*x_14 + 120*x_15 + 45*x_16 + 10*x_17 + x_18 + x_8 + 10*x_9 - 3410,
      10*x_10 + 45*x_11 + 120*x_12 + 210*x_13 + 252*x_14 + 210*x_15 + 120*x_16 + 45*x_17 + 10*x_18 + x_19 + x_9 - 3410,
      x_10 + 10*x_11 + 45*x_12 + 120*x_13 + 210*x_14 + 252*x_15 + 210*x_16 + 120*x_17 + 45*x_18 + 10*x_19 + x_20 - 3410,
      x_11 + 10*x_12 + 45*x_13 + 120*x_14 + 210*x_15 + 252*x_16 + 210*x_17 + 120*x_18 + 45*x_19 + 10*x_20 + x_21 - 3410,
      x_12 + 10*x_13 + 45*x_14 + 120*x_15 + 210*x_16 + 252*x_17 + 210*x_18 + 120*x_19 + 45*x_20 + 10*x_21 + x_22 - 3410,
      x_13 + 10*x_14 + 45*x_15 + 120*x_16 + 210*x_17 + 252*x_18 + 210*x_19 + 120*x_20 + 45*x_21 + 10*x_22 + x_23 - 3410,
      x_14 + 10*x_15 + 45*x_16 + 120*x_17 + 210*x_18 + 252*x_19 + 210*x_20 + 120*x_21 + 45*x_22 + 10*x_23 + x_24 - 3410,
      x_15 + 10*x_16 + 45*x_17 + 120*x_18 + 210*x_19 + 252*x_20 + 210*x_21 + 120*x_22 + 45*x_23 + 10*x_24 + x_25 - 3410,
      x_16 + 10*x_17 + 45*x_18 + 120*x_19 + 210*x_20 + 252*x_21 + 210*x_22 + 120*x_23 + 45*x_24 + 10*x_25 + x_26 - 3410],
     12: [-x_1 - 55*x_10 - 11*x_11 - x_12 - 11*x_2 - 55*x_3 - 165*x_4 - 330*x_5 - 462*x_6 - 462*x_7 - 330*x_8 - 165*x_9 + 6830,
      -165*x_10 - 55*x_11 - 11*x_12 - x_13 - x_2 - 11*x_3 - 55*x_4 - 165*x_5 - 330*x_6 - 462*x_7 - 462*x_8 - 330*x_9 + 6830,
      -330*x_10 - 165*x_11 - 55*x_12 - 11*x_13 - x_14 - x_3 - 11*x_4 - 55*x_5 - 165*x_6 - 330*x_7 - 462*x_8 - 462*x_9 + 6830,
      -462*x_10 - 330*x_11 - 165*x_12 - 55*x_13 - 11*x_14 - x_15 - x_4 - 11*x_5 - 55*x_6 - 165*x_7 - 330*x_8 - 462*x_9 + 6830,
      -462*x_10 - 462*x_11 - 330*x_12 - 165*x_13 - 55*x_14 - 11*x_15 - x_16 - x_5 - 11*x_6 - 55*x_7 - 165*x_8 - 330*x_9 + 6830,
      -330*x_10 - 462*x_11 - 462*x_12 - 330*x_13 - 165*x_14 - 55*x_15 - 11*x_16 - x_17 - x_6 - 11*x_7 - 55*x_8 - 165*x_9 + 6830,
      -165*x_10 - 330*x_11 - 462*x_12 - 462*x_13 - 330*x_14 - 165*x_15 - 55*x_16 - 11*x_17 - x_18 - x_7 - 11*x_8 - 55*x_9 + 6830,
      -55*x_10 - 165*x_11 - 330*x_12 - 462*x_13 - 462*x_14 - 330*x_15 - 165*x_16 - 55*x_17 - 11*x_18 - x_19 - x_8 - 11*x_9 + 6830,
      -11*x_10 - 55*x_11 - 165*x_12 - 330*x_13 - 462*x_14 - 462*x_15 - 330*x_16 - 165*x_17 - 55*x_18 - 11*x_19 - x_20 - x_9 + 6830,
      -x_10 - 11*x_11 - 55*x_12 - 165*x_13 - 330*x_14 - 462*x_15 - 462*x_16 - 330*x_17 - 165*x_18 - 55*x_19 - 11*x_20 - x_21 + 6830,
      -x_11 - 11*x_12 - 55*x_13 - 165*x_14 - 330*x_15 - 462*x_16 - 462*x_17 - 330*x_18 - 165*x_19 - 55*x_20 - 11*x_21 - x_22 + 6830,
      -x_12 - 11*x_13 - 55*x_14 - 165*x_15 - 330*x_16 - 462*x_17 - 462*x_18 - 330*x_19 - 165*x_20 - 55*x_21 - 11*x_22 - x_23 + 6830,
      -x_13 - 11*x_14 - 55*x_15 - 165*x_16 - 330*x_17 - 462*x_18 - 462*x_19 - 330*x_20 - 165*x_21 - 55*x_22 - 11*x_23 - x_24 + 6830,
      -x_14 - 11*x_15 - 55*x_16 - 165*x_17 - 330*x_18 - 462*x_19 - 462*x_20 - 330*x_21 - 165*x_22 - 55*x_23 - 11*x_24 - x_25 + 6830,
      -x_15 - 11*x_16 - 55*x_17 - 165*x_18 - 330*x_19 - 462*x_20 - 462*x_21 - 330*x_22 - 165*x_23 - 55*x_24 - 11*x_25 - x_26 + 6830],
     13: [x_1 + 220*x_10 + 66*x_11 + 12*x_12 + x_13 + 12*x_2 + 66*x_3 + 220*x_4 + 495*x_5 + 792*x_6 + 924*x_7 + 792*x_8 + 495*x_9 - 13650,
      495*x_10 + 220*x_11 + 66*x_12 + 12*x_13 + x_14 + x_2 + 12*x_3 + 66*x_4 + 220*x_5 + 495*x_6 + 792*x_7 + 924*x_8 + 792*x_9 - 13650,
      792*x_10 + 495*x_11 + 220*x_12 + 66*x_13 + 12*x_14 + x_15 + x_3 + 12*x_4 + 66*x_5 + 220*x_6 + 495*x_7 + 792*x_8 + 924*x_9 - 13650,
      924*x_10 + 792*x_11 + 495*x_12 + 220*x_13 + 66*x_14 + 12*x_15 + x_16 + x_4 + 12*x_5 + 66*x_6 + 220*x_7 + 495*x_8 + 792*x_9 - 13650,
      792*x_10 + 924*x_11 + 792*x_12 + 495*x_13 + 220*x_14 + 66*x_15 + 12*x_16 + x_17 + x_5 + 12*x_6 + 66*x_7 + 220*x_8 + 495*x_9 - 13650,
      495*x_10 + 792*x_11 + 924*x_12 + 792*x_13 + 495*x_14 + 220*x_15 + 66*x_16 + 12*x_17 + x_18 + x_6 + 12*x_7 + 66*x_8 + 220*x_9 - 13650,
      220*x_10 + 495*x_11 + 792*x_12 + 924*x_13 + 792*x_14 + 495*x_15 + 220*x_16 + 66*x_17 + 12*x_18 + x_19 + x_7 + 12*x_8 + 66*x_9 - 13650,
      66*x_10 + 220*x_11 + 495*x_12 + 792*x_13 + 924*x_14 + 792*x_15 + 495*x_16 + 220*x_17 + 66*x_18 + 12*x_19 + x_20 + x_8 + 12*x_9 - 13650,
      12*x_10 + 66*x_11 + 220*x_12 + 495*x_13 + 792*x_14 + 924*x_15 + 792*x_16 + 495*x_17 + 220*x_18 + 66*x_19 + 12*x_20 + x_21 + x_9 - 13650,
      x_10 + 12*x_11 + 66*x_12 + 220*x_13 + 495*x_14 + 792*x_15 + 924*x_16 + 792*x_17 + 495*x_18 + 220*x_19 + 66*x_20 + 12*x_21 + x_22 - 13650,
      x_11 + 12*x_12 + 66*x_13 + 220*x_14 + 495*x_15 + 792*x_16 + 924*x_17 + 792*x_18 + 495*x_19 + 220*x_20 + 66*x_21 + 12*x_22 + x_23 - 13650,
      x_12 + 12*x_13 + 66*x_14 + 220*x_15 + 495*x_16 + 792*x_17 + 924*x_18 + 792*x_19 + 495*x_20 + 220*x_21 + 66*x_22 + 12*x_23 + x_24 - 13650,
      x_13 + 12*x_14 + 66*x_15 + 220*x_16 + 495*x_17 + 792*x_18 + 924*x_19 + 792*x_20 + 495*x_21 + 220*x_22 + 66*x_23 + 12*x_24 + x_25 - 13650,
      x_14 + 12*x_15 + 66*x_16 + 220*x_17 + 495*x_18 + 792*x_19 + 924*x_20 + 792*x_21 + 495*x_22 + 220*x_23 + 66*x_24 + 12*x_25 + x_26 - 13650],
     14: [-x_1 - 715*x_10 - 286*x_11 - 78*x_12 - 13*x_13 - x_14 - 13*x_2 - 78*x_3 - 286*x_4 - 715*x_5 - 1287*x_6 - 1716*x_7 - 1716*x_8 - 1287*x_9 + 27310,
      -1287*x_10 - 715*x_11 - 286*x_12 - 78*x_13 - 13*x_14 - x_15 - x_2 - 13*x_3 - 78*x_4 - 286*x_5 - 715*x_6 - 1287*x_7 - 1716*x_8 - 1716*x_9 + 27310,
      -1716*x_10 - 1287*x_11 - 715*x_12 - 286*x_13 - 78*x_14 - 13*x_15 - x_16 - x_3 - 13*x_4 - 78*x_5 - 286*x_6 - 715*x_7 - 1287*x_8 - 1716*x_9 + 27310,
      -1716*x_10 - 1716*x_11 - 1287*x_12 - 715*x_13 - 286*x_14 - 78*x_15 - 13*x_16 - x_17 - x_4 - 13*x_5 - 78*x_6 - 286*x_7 - 715*x_8 - 1287*x_9 + 27310,
      -1287*x_10 - 1716*x_11 - 1716*x_12 - 1287*x_13 - 715*x_14 - 286*x_15 - 78*x_16 - 13*x_17 - x_18 - x_5 - 13*x_6 - 78*x_7 - 286*x_8 - 715*x_9 + 27310,
      -715*x_10 - 1287*x_11 - 1716*x_12 - 1716*x_13 - 1287*x_14 - 715*x_15 - 286*x_16 - 78*x_17 - 13*x_18 - x_19 - x_6 - 13*x_7 - 78*x_8 - 286*x_9 + 27310,
      -286*x_10 - 715*x_11 - 1287*x_12 - 1716*x_13 - 1716*x_14 - 1287*x_15 - 715*x_16 - 286*x_17 - 78*x_18 - 13*x_19 - x_20 - x_7 - 13*x_8 - 78*x_9 + 27310,
      -78*x_10 - 286*x_11 - 715*x_12 - 1287*x_13 - 1716*x_14 - 1716*x_15 - 1287*x_16 - 715*x_17 - 286*x_18 - 78*x_19 - 13*x_20 - x_21 - x_8 - 13*x_9 + 27310,
      -13*x_10 - 78*x_11 - 286*x_12 - 715*x_13 - 1287*x_14 - 1716*x_15 - 1716*x_16 - 1287*x_17 - 715*x_18 - 286*x_19 - 78*x_20 - 13*x_21 - x_22 - x_9 + 27310,
      -x_10 - 13*x_11 - 78*x_12 - 286*x_13 - 715*x_14 - 1287*x_15 - 1716*x_16 - 1716*x_17 - 1287*x_18 - 715*x_19 - 286*x_20 - 78*x_21 - 13*x_22 - x_23 + 27310,
      -x_11 - 13*x_12 - 78*x_13 - 286*x_14 - 715*x_15 - 1287*x_16 - 1716*x_17 - 1716*x_18 - 1287*x_19 - 715*x_20 - 286*x_21 - 78*x_22 - 13*x_23 - x_24 + 27310,
      -x_12 - 13*x_13 - 78*x_14 - 286*x_15 - 715*x_16 - 1287*x_17 - 1716*x_18 - 1716*x_19 - 1287*x_20 - 715*x_21 - 286*x_22 - 78*x_23 - 13*x_24 - x_25 + 27310,
      -x_13 - 13*x_14 - 78*x_15 - 286*x_16 - 715*x_17 - 1287*x_18 - 1716*x_19 - 1716*x_20 - 1287*x_21 - 715*x_22 - 286*x_23 - 78*x_24 - 13*x_25 - x_26 + 27310],
     15: [x_1 + 2002*x_10 + 1001*x_11 + 364*x_12 + 91*x_13 + 14*x_14 + x_15 + 14*x_2 + 91*x_3 + 364*x_4 + 1001*x_5 + 2002*x_6 + 3003*x_7 + 3432*x_8 + 3003*x_9 - 54610,
      3003*x_10 + 2002*x_11 + 1001*x_12 + 364*x_13 + 91*x_14 + 14*x_15 + x_16 + x_2 + 14*x_3 + 91*x_4 + 364*x_5 + 1001*x_6 + 2002*x_7 + 3003*x_8 + 3432*x_9 - 54610,
      3432*x_10 + 3003*x_11 + 2002*x_12 + 1001*x_13 + 364*x_14 + 91*x_15 + 14*x_16 + x_17 + x_3 + 14*x_4 + 91*x_5 + 364*x_6 + 1001*x_7 + 2002*x_8 + 3003*x_9 - 54610,
      3003*x_10 + 3432*x_11 + 3003*x_12 + 2002*x_13 + 1001*x_14 + 364*x_15 + 91*x_16 + 14*x_17 + x_18 + x_4 + 14*x_5 + 91*x_6 + 364*x_7 + 1001*x_8 + 2002*x_9 - 54610,
      2002*x_10 + 3003*x_11 + 3432*x_12 + 3003*x_13 + 2002*x_14 + 1001*x_15 + 364*x_16 + 91*x_17 + 14*x_18 + x_19 + x_5 + 14*x_6 + 91*x_7 + 364*x_8 + 1001*x_9 - 54610,
      1001*x_10 + 2002*x_11 + 3003*x_12 + 3432*x_13 + 3003*x_14 + 2002*x_15 + 1001*x_16 + 364*x_17 + 91*x_18 + 14*x_19 + x_20 + x_6 + 14*x_7 + 91*x_8 + 364*x_9 - 54610,
      364*x_10 + 1001*x_11 + 2002*x_12 + 3003*x_13 + 3432*x_14 + 3003*x_15 + 2002*x_16 + 1001*x_17 + 364*x_18 + 91*x_19 + 14*x_20 + x_21 + x_7 + 14*x_8 + 91*x_9 - 54610,
      91*x_10 + 364*x_11 + 1001*x_12 + 2002*x_13 + 3003*x_14 + 3432*x_15 + 3003*x_16 + 2002*x_17 + 1001*x_18 + 364*x_19 + 91*x_20 + 14*x_21 + x_22 + x_8 + 14*x_9 - 54610,
      14*x_10 + 91*x_11 + 364*x_12 + 1001*x_13 + 2002*x_14 + 3003*x_15 + 3432*x_16 + 3003*x_17 + 2002*x_18 + 1001*x_19 + 364*x_20 + 91*x_21 + 14*x_22 + x_23 + x_9 - 54610,
      x_10 + 14*x_11 + 91*x_12 + 364*x_13 + 1001*x_14 + 2002*x_15 + 3003*x_16 + 3432*x_17 + 3003*x_18 + 2002*x_19 + 1001*x_20 + 364*x_21 + 91*x_22 + 14*x_23 + x_24 - 54610,
      x_11 + 14*x_12 + 91*x_13 + 364*x_14 + 1001*x_15 + 2002*x_16 + 3003*x_17 + 3432*x_18 + 3003*x_19 + 2002*x_20 + 1001*x_21 + 364*x_22 + 91*x_23 + 14*x_24 + x_25 - 54610,
      x_12 + 14*x_13 + 91*x_14 + 364*x_15 + 1001*x_16 + 2002*x_17 + 3003*x_18 + 3432*x_19 + 3003*x_20 + 2002*x_21 + 1001*x_22 + 364*x_23 + 91*x_24 + 14*x_25 + x_26 - 54610],
     16: [-x_1 - 5005*x_10 - 3003*x_11 - 1365*x_12 - 455*x_13 - 105*x_14 - 15*x_15 - x_16 - 15*x_2 - 105*x_3 - 455*x_4 - 1365*x_5 - 3003*x_6 - 5005*x_7 - 6435*x_8 - 6435*x_9 + 109230,
      -6435*x_10 - 5005*x_11 - 3003*x_12 - 1365*x_13 - 455*x_14 - 105*x_15 - 15*x_16 - x_17 - x_2 - 15*x_3 - 105*x_4 - 455*x_5 - 1365*x_6 - 3003*x_7 - 5005*x_8 - 6435*x_9 + 109230,
      -6435*x_10 - 6435*x_11 - 5005*x_12 - 3003*x_13 - 1365*x_14 - 455*x_15 - 105*x_16 - 15*x_17 - x_18 - x_3 - 15*x_4 - 105*x_5 - 455*x_6 - 1365*x_7 - 3003*x_8 - 5005*x_9 + 109230,
      -5005*x_10 - 6435*x_11 - 6435*x_12 - 5005*x_13 - 3003*x_14 - 1365*x_15 - 455*x_16 - 105*x_17 - 15*x_18 - x_19 - x_4 - 15*x_5 - 105*x_6 - 455*x_7 - 1365*x_8 - 3003*x_9 + 109230,
      -3003*x_10 - 5005*x_11 - 6435*x_12 - 6435*x_13 - 5005*x_14 - 3003*x_15 - 1365*x_16 - 455*x_17 - 105*x_18 - 15*x_19 - x_20 - x_5 - 15*x_6 - 105*x_7 - 455*x_8 - 1365*x_9 + 109230,
      -1365*x_10 - 3003*x_11 - 5005*x_12 - 6435*x_13 - 6435*x_14 - 5005*x_15 - 3003*x_16 - 1365*x_17 - 455*x_18 - 105*x_19 - 15*x_20 - x_21 - x_6 - 15*x_7 - 105*x_8 - 455*x_9 + 109230,
      -455*x_10 - 1365*x_11 - 3003*x_12 - 5005*x_13 - 6435*x_14 - 6435*x_15 - 5005*x_16 - 3003*x_17 - 1365*x_18 - 455*x_19 - 105*x_20 - 15*x_21 - x_22 - x_7 - 15*x_8 - 105*x_9 + 109230,
      -105*x_10 - 455*x_11 - 1365*x_12 - 3003*x_13 - 5005*x_14 - 6435*x_15 - 6435*x_16 - 5005*x_17 - 3003*x_18 - 1365*x_19 - 455*x_20 - 105*x_21 - 15*x_22 - x_23 - x_8 - 15*x_9 + 109230,
      -15*x_10 - 105*x_11 - 455*x_12 - 1365*x_13 - 3003*x_14 - 5005*x_15 - 6435*x_16 - 6435*x_17 - 5005*x_18 - 3003*x_19 - 1365*x_20 - 455*x_21 - 105*x_22 - 15*x_23 - x_24 - x_9 + 109230,
      -x_10 - 15*x_11 - 105*x_12 - 455*x_13 - 1365*x_14 - 3003*x_15 - 5005*x_16 - 6435*x_17 - 6435*x_18 - 5005*x_19 - 3003*x_20 - 1365*x_21 - 455*x_22 - 105*x_23 - 15*x_24 - x_25 + 109230,
      -x_11 - 15*x_12 - 105*x_13 - 455*x_14 - 1365*x_15 - 3003*x_16 - 5005*x_17 - 6435*x_18 - 6435*x_19 - 5005*x_20 - 3003*x_21 - 1365*x_22 - 455*x_23 - 105*x_24 - 15*x_25 - x_26 + 109230],
     17: [x_1 + 11440*x_10 + 8008*x_11 + 4368*x_12 + 1820*x_13 + 560*x_14 + 120*x_15 + 16*x_16 + x_17 + 16*x_2 + 120*x_3 + 560*x_4 + 1820*x_5 + 4368*x_6 + 8008*x_7 + 11440*x_8 + 12870*x_9 - 218450,
      12870*x_10 + 11440*x_11 + 8008*x_12 + 4368*x_13 + 1820*x_14 + 560*x_15 + 120*x_16 + 16*x_17 + x_18 + x_2 + 16*x_3 + 120*x_4 + 560*x_5 + 1820*x_6 + 4368*x_7 + 8008*x_8 + 11440*x_9 - 218450,
      11440*x_10 + 12870*x_11 + 11440*x_12 + 8008*x_13 + 4368*x_14 + 1820*x_15 + 560*x_16 + 120*x_17 + 16*x_18 + x_19 + x_3 + 16*x_4 + 120*x_5 + 560*x_6 + 1820*x_7 + 4368*x_8 + 8008*x_9 - 218450,
      8008*x_10 + 11440*x_11 + 12870*x_12 + 11440*x_13 + 8008*x_14 + 4368*x_15 + 1820*x_16 + 560*x_17 + 120*x_18 + 16*x_19 + x_20 + x_4 + 16*x_5 + 120*x_6 + 560*x_7 + 1820*x_8 + 4368*x_9 - 218450,
      4368*x_10 + 8008*x_11 + 11440*x_12 + 12870*x_13 + 11440*x_14 + 8008*x_15 + 4368*x_16 + 1820*x_17 + 560*x_18 + 120*x_19 + 16*x_20 + x_21 + x_5 + 16*x_6 + 120*x_7 + 560*x_8 + 1820*x_9 - 218450,
      1820*x_10 + 4368*x_11 + 8008*x_12 + 11440*x_13 + 12870*x_14 + 11440*x_15 + 8008*x_16 + 4368*x_17 + 1820*x_18 + 560*x_19 + 120*x_20 + 16*x_21 + x_22 + x_6 + 16*x_7 + 120*x_8 + 560*x_9 - 218450,
      560*x_10 + 1820*x_11 + 4368*x_12 + 8008*x_13 + 11440*x_14 + 12870*x_15 + 11440*x_16 + 8008*x_17 + 4368*x_18 + 1820*x_19 + 560*x_20 + 120*x_21 + 16*x_22 + x_23 + x_7 + 16*x_8 + 120*x_9 - 218450,
      120*x_10 + 560*x_11 + 1820*x_12 + 4368*x_13 + 8008*x_14 + 11440*x_15 + 12870*x_16 + 11440*x_17 + 8008*x_18 + 4368*x_19 + 1820*x_20 + 560*x_21 + 120*x_22 + 16*x_23 + x_24 + x_8 + 16*x_9 - 218450,
      16*x_10 + 120*x_11 + 560*x_12 + 1820*x_13 + 4368*x_14 + 8008*x_15 + 11440*x_16 + 12870*x_17 + 11440*x_18 + 8008*x_19 + 4368*x_20 + 1820*x_21 + 560*x_22 + 120*x_23 + 16*x_24 + x_25 + x_9 - 218450,
      x_10 + 16*x_11 + 120*x_12 + 560*x_13 + 1820*x_14 + 4368*x_15 + 8008*x_16 + 11440*x_17 + 12870*x_18 + 11440*x_19 + 8008*x_20 + 4368*x_21 + 1820*x_22 + 560*x_23 + 120*x_24 + 16*x_25 + x_26 - 218450],
     18: [-x_1 - 24310*x_10 - 19448*x_11 - 12376*x_12 - 6188*x_13 - 2380*x_14 - 680*x_15 - 136*x_16 - 17*x_17 - x_18 - 17*x_2 - 136*x_3 - 680*x_4 - 2380*x_5 - 6188*x_6 - 12376*x_7 - 19448*x_8 - 24310*x_9 + 436910,
      -24310*x_10 - 24310*x_11 - 19448*x_12 - 12376*x_13 - 6188*x_14 - 2380*x_15 - 680*x_16 - 136*x_17 - 17*x_18 - x_19 - x_2 - 17*x_3 - 136*x_4 - 680*x_5 - 2380*x_6 - 6188*x_7 - 12376*x_8 - 19448*x_9 + 436910,
      -19448*x_10 - 24310*x_11 - 24310*x_12 - 19448*x_13 - 12376*x_14 - 6188*x_15 - 2380*x_16 - 680*x_17 - 136*x_18 - 17*x_19 - x_20 - x_3 - 17*x_4 - 136*x_5 - 680*x_6 - 2380*x_7 - 6188*x_8 - 12376*x_9 + 436910,
      -12376*x_10 - 19448*x_11 - 24310*x_12 - 24310*x_13 - 19448*x_14 - 12376*x_15 - 6188*x_16 - 2380*x_17 - 680*x_18 - 136*x_19 - 17*x_20 - x_21 - x_4 - 17*x_5 - 136*x_6 - 680*x_7 - 2380*x_8 - 6188*x_9 + 436910,
      -6188*x_10 - 12376*x_11 - 19448*x_12 - 24310*x_13 - 24310*x_14 - 19448*x_15 - 12376*x_16 - 6188*x_17 - 2380*x_18 - 680*x_19 - 136*x_20 - 17*x_21 - x_22 - x_5 - 17*x_6 - 136*x_7 - 680*x_8 - 2380*x_9 + 436910,
      -2380*x_10 - 6188*x_11 - 12376*x_12 - 19448*x_13 - 24310*x_14 - 24310*x_15 - 19448*x_16 - 12376*x_17 - 6188*x_18 - 2380*x_19 - 680*x_20 - 136*x_21 - 17*x_22 - x_23 - x_6 - 17*x_7 - 136*x_8 - 680*x_9 + 436910,
      -680*x_10 - 2380*x_11 - 6188*x_12 - 12376*x_13 - 19448*x_14 - 24310*x_15 - 24310*x_16 - 19448*x_17 - 12376*x_18 - 6188*x_19 - 2380*x_20 - 680*x_21 - 136*x_22 - 17*x_23 - x_24 - x_7 - 17*x_8 - 136*x_9 + 436910,
      -136*x_10 - 680*x_11 - 2380*x_12 - 6188*x_13 - 12376*x_14 - 19448*x_15 - 24310*x_16 - 24310*x_17 - 19448*x_18 - 12376*x_19 - 6188*x_20 - 2380*x_21 - 680*x_22 - 136*x_23 - 17*x_24 - x_25 - x_8 - 17*x_9 + 436910,
      -17*x_10 - 136*x_11 - 680*x_12 - 2380*x_13 - 6188*x_14 - 12376*x_15 - 19448*x_16 - 24310*x_17 - 24310*x_18 - 19448*x_19 - 12376*x_20 - 6188*x_21 - 2380*x_22 - 680*x_23 - 136*x_24 - 17*x_25 - x_26 - x_9 + 436910],
     19: [x_1 + 48620*x_10 + 43758*x_11 + 31824*x_12 + 18564*x_13 + 8568*x_14 + 3060*x_15 + 816*x_16 + 153*x_17 + 18*x_18 + x_19 + 18*x_2 + 153*x_3 + 816*x_4 + 3060*x_5 + 8568*x_6 + 18564*x_7 + 31824*x_8 + 43758*x_9 - 873810,
      43758*x_10 + 48620*x_11 + 43758*x_12 + 31824*x_13 + 18564*x_14 + 8568*x_15 + 3060*x_16 + 816*x_17 + 153*x_18 + 18*x_19 + x_2 + x_20 + 18*x_3 + 153*x_4 + 816*x_5 + 3060*x_6 + 8568*x_7 + 18564*x_8 + 31824*x_9 - 873810,
      31824*x_10 + 43758*x_11 + 48620*x_12 + 43758*x_13 + 31824*x_14 + 18564*x_15 + 8568*x_16 + 3060*x_17 + 816*x_18 + 153*x_19 + 18*x_20 + x_21 + x_3 + 18*x_4 + 153*x_5 + 816*x_6 + 3060*x_7 + 8568*x_8 + 18564*x_9 - 873810,
      18564*x_10 + 31824*x_11 + 43758*x_12 + 48620*x_13 + 43758*x_14 + 31824*x_15 + 18564*x_16 + 8568*x_17 + 3060*x_18 + 816*x_19 + 153*x_20 + 18*x_21 + x_22 + x_4 + 18*x_5 + 153*x_6 + 816*x_7 + 3060*x_8 + 8568*x_9 - 873810,
      8568*x_10 + 18564*x_11 + 31824*x_12 + 43758*x_13 + 48620*x_14 + 43758*x_15 + 31824*x_16 + 18564*x_17 + 8568*x_18 + 3060*x_19 + 816*x_20 + 153*x_21 + 18*x_22 + x_23 + x_5 + 18*x_6 + 153*x_7 + 816*x_8 + 3060*x_9 - 873810,
      3060*x_10 + 8568*x_11 + 18564*x_12 + 31824*x_13 + 43758*x_14 + 48620*x_15 + 43758*x_16 + 31824*x_17 + 18564*x_18 + 8568*x_19 + 3060*x_20 + 816*x_21 + 153*x_22 + 18*x_23 + x_24 + x_6 + 18*x_7 + 153*x_8 + 816*x_9 - 873810,
      816*x_10 + 3060*x_11 + 8568*x_12 + 18564*x_13 + 31824*x_14 + 43758*x_15 + 48620*x_16 + 43758*x_17 + 31824*x_18 + 18564*x_19 + 8568*x_20 + 3060*x_21 + 816*x_22 + 153*x_23 + 18*x_24 + x_25 + x_7 + 18*x_8 + 153*x_9 - 873810,
      153*x_10 + 816*x_11 + 3060*x_12 + 8568*x_13 + 18564*x_14 + 31824*x_15 + 43758*x_16 + 48620*x_17 + 43758*x_18 + 31824*x_19 + 18564*x_20 + 8568*x_21 + 3060*x_22 + 816*x_23 + 153*x_24 + 18*x_25 + x_26 + x_8 + 18*x_9 - 873810],
     20: [-x_1 - 92378*x_10 - 92378*x_11 - 75582*x_12 - 50388*x_13 - 27132*x_14 - 11628*x_15 - 3876*x_16 - 969*x_17 - 171*x_18 - 19*x_19 - 19*x_2 - x_20 - 171*x_3 - 969*x_4 - 3876*x_5 - 11628*x_6 - 27132*x_7 - 50388*x_8 - 75582*x_9 + 1747630,
      -75582*x_10 - 92378*x_11 - 92378*x_12 - 75582*x_13 - 50388*x_14 - 27132*x_15 - 11628*x_16 - 3876*x_17 - 969*x_18 - 171*x_19 - x_2 - 19*x_20 - x_21 - 19*x_3 - 171*x_4 - 969*x_5 - 3876*x_6 - 11628*x_7 - 27132*x_8 - 50388*x_9 + 1747630,
      -50388*x_10 - 75582*x_11 - 92378*x_12 - 92378*x_13 - 75582*x_14 - 50388*x_15 - 27132*x_16 - 11628*x_17 - 3876*x_18 - 969*x_19 - 171*x_20 - 19*x_21 - x_22 - x_3 - 19*x_4 - 171*x_5 - 969*x_6 - 3876*x_7 - 11628*x_8 - 27132*x_9 + 1747630,
      -27132*x_10 - 50388*x_11 - 75582*x_12 - 92378*x_13 - 92378*x_14 - 75582*x_15 - 50388*x_16 - 27132*x_17 - 11628*x_18 - 3876*x_19 - 969*x_20 - 171*x_21 - 19*x_22 - x_23 - x_4 - 19*x_5 - 171*x_6 - 969*x_7 - 3876*x_8 - 11628*x_9 + 1747630,
      -11628*x_10 - 27132*x_11 - 50388*x_12 - 75582*x_13 - 92378*x_14 - 92378*x_15 - 75582*x_16 - 50388*x_17 - 27132*x_18 - 11628*x_19 - 3876*x_20 - 969*x_21 - 171*x_22 - 19*x_23 - x_24 - x_5 - 19*x_6 - 171*x_7 - 969*x_8 - 3876*x_9 + 1747630,
      -3876*x_10 - 11628*x_11 - 27132*x_12 - 50388*x_13 - 75582*x_14 - 92378*x_15 - 92378*x_16 - 75582*x_17 - 50388*x_18 - 27132*x_19 - 11628*x_20 - 3876*x_21 - 969*x_22 - 171*x_23 - 19*x_24 - x_25 - x_6 - 19*x_7 - 171*x_8 - 969*x_9 + 1747630,
      -969*x_10 - 3876*x_11 - 11628*x_12 - 27132*x_13 - 50388*x_14 - 75582*x_15 - 92378*x_16 - 92378*x_17 - 75582*x_18 - 50388*x_19 - 27132*x_20 - 11628*x_21 - 3876*x_22 - 969*x_23 - 171*x_24 - 19*x_25 - x_26 - x_7 - 19*x_8 - 171*x_9 + 1747630],
     21: [x_1 + 167960*x_10 + 184756*x_11 + 167960*x_12 + 125970*x_13 + 77520*x_14 + 38760*x_15 + 15504*x_16 + 4845*x_17 + 1140*x_18 + 190*x_19 + 20*x_2 + 20*x_20 + x_21 + 190*x_3 + 1140*x_4 + 4845*x_5 + 15504*x_6 + 38760*x_7 + 77520*x_8 + 125970*x_9 - 3495250,
      125970*x_10 + 167960*x_11 + 184756*x_12 + 167960*x_13 + 125970*x_14 + 77520*x_15 + 38760*x_16 + 15504*x_17 + 4845*x_18 + 1140*x_19 + x_2 + 190*x_20 + 20*x_21 + x_22 + 20*x_3 + 190*x_4 + 1140*x_5 + 4845*x_6 + 15504*x_7 + 38760*x_8 + 77520*x_9 - 3495250,
      77520*x_10 + 125970*x_11 + 167960*x_12 + 184756*x_13 + 167960*x_14 + 125970*x_15 + 77520*x_16 + 38760*x_17 + 15504*x_18 + 4845*x_19 + 1140*x_20 + 190*x_21 + 20*x_22 + x_23 + x_3 + 20*x_4 + 190*x_5 + 1140*x_6 + 4845*x_7 + 15504*x_8 + 38760*x_9 - 3495250,
      38760*x_10 + 77520*x_11 + 125970*x_12 + 167960*x_13 + 184756*x_14 + 167960*x_15 + 125970*x_16 + 77520*x_17 + 38760*x_18 + 15504*x_19 + 4845*x_20 + 1140*x_21 + 190*x_22 + 20*x_23 + x_24 + x_4 + 20*x_5 + 190*x_6 + 1140*x_7 + 4845*x_8 + 15504*x_9 - 3495250,
      15504*x_10 + 38760*x_11 + 77520*x_12 + 125970*x_13 + 167960*x_14 + 184756*x_15 + 167960*x_16 + 125970*x_17 + 77520*x_18 + 38760*x_19 + 15504*x_20 + 4845*x_21 + 1140*x_22 + 190*x_23 + 20*x_24 + x_25 + x_5 + 20*x_6 + 190*x_7 + 1140*x_8 + 4845*x_9 - 3495250,
      4845*x_10 + 15504*x_11 + 38760*x_12 + 77520*x_13 + 125970*x_14 + 167960*x_15 + 184756*x_16 + 167960*x_17 + 125970*x_18 + 77520*x_19 + 38760*x_20 + 15504*x_21 + 4845*x_22 + 1140*x_23 + 190*x_24 + 20*x_25 + x_26 + x_6 + 20*x_7 + 190*x_8 + 1140*x_9 - 3495250],
     22: [-x_1 - 293930*x_10 - 352716*x_11 - 352716*x_12 - 293930*x_13 - 203490*x_14 - 116280*x_15 - 54264*x_16 - 20349*x_17 - 5985*x_18 - 1330*x_19 - 21*x_2 - 210*x_20 - 21*x_21 - x_22 - 210*x_3 - 1330*x_4 - 5985*x_5 - 20349*x_6 - 54264*x_7 - 116280*x_8 - 203490*x_9 + 6990510,
      -203490*x_10 - 293930*x_11 - 352716*x_12 - 352716*x_13 - 293930*x_14 - 203490*x_15 - 116280*x_16 - 54264*x_17 - 20349*x_18 - 5985*x_19 - x_2 - 1330*x_20 - 210*x_21 - 21*x_22 - x_23 - 21*x_3 - 210*x_4 - 1330*x_5 - 5985*x_6 - 20349*x_7 - 54264*x_8 - 116280*x_9 + 6990510,
      -116280*x_10 - 203490*x_11 - 293930*x_12 - 352716*x_13 - 352716*x_14 - 293930*x_15 - 203490*x_16 - 116280*x_17 - 54264*x_18 - 20349*x_19 - 5985*x_20 - 1330*x_21 - 210*x_22 - 21*x_23 - x_24 - x_3 - 21*x_4 - 210*x_5 - 1330*x_6 - 5985*x_7 - 20349*x_8 - 54264*x_9 + 6990510,
      -54264*x_10 - 116280*x_11 - 203490*x_12 - 293930*x_13 - 352716*x_14 - 352716*x_15 - 293930*x_16 - 203490*x_17 - 116280*x_18 - 54264*x_19 - 20349*x_20 - 5985*x_21 - 1330*x_22 - 210*x_23 - 21*x_24 - x_25 - x_4 - 21*x_5 - 210*x_6 - 1330*x_7 - 5985*x_8 - 20349*x_9 + 6990510,
      -20349*x_10 - 54264*x_11 - 116280*x_12 - 203490*x_13 - 293930*x_14 - 352716*x_15 - 352716*x_16 - 293930*x_17 - 203490*x_18 - 116280*x_19 - 54264*x_20 - 20349*x_21 - 5985*x_22 - 1330*x_23 - 210*x_24 - 21*x_25 - x_26 - x_5 - 21*x_6 - 210*x_7 - 1330*x_8 - 5985*x_9 + 6990510],
     23: [x_1 + 497420*x_10 + 646646*x_11 + 705432*x_12 + 646646*x_13 + 497420*x_14 + 319770*x_15 + 170544*x_16 + 74613*x_17 + 26334*x_18 + 7315*x_19 + 22*x_2 + 1540*x_20 + 231*x_21 + 22*x_22 + x_23 + 231*x_3 + 1540*x_4 + 7315*x_5 + 26334*x_6 + 74613*x_7 + 170544*x_8 + 319770*x_9 - 13981010,
      319770*x_10 + 497420*x_11 + 646646*x_12 + 705432*x_13 + 646646*x_14 + 497420*x_15 + 319770*x_16 + 170544*x_17 + 74613*x_18 + 26334*x_19 + x_2 + 7315*x_20 + 1540*x_21 + 231*x_22 + 22*x_23 + x_24 + 22*x_3 + 231*x_4 + 1540*x_5 + 7315*x_6 + 26334*x_7 + 74613*x_8 + 170544*x_9 - 13981010,
      170544*x_10 + 319770*x_11 + 497420*x_12 + 646646*x_13 + 705432*x_14 + 646646*x_15 + 497420*x_16 + 319770*x_17 + 170544*x_18 + 74613*x_19 + 26334*x_20 + 7315*x_21 + 1540*x_22 + 231*x_23 + 22*x_24 + x_25 + x_3 + 22*x_4 + 231*x_5 + 1540*x_6 + 7315*x_7 + 26334*x_8 + 74613*x_9 - 13981010,
      74613*x_10 + 170544*x_11 + 319770*x_12 + 497420*x_13 + 646646*x_14 + 705432*x_15 + 646646*x_16 + 497420*x_17 + 319770*x_18 + 170544*x_19 + 74613*x_20 + 26334*x_21 + 7315*x_22 + 1540*x_23 + 231*x_24 + 22*x_25 + x_26 + x_4 + 22*x_5 + 231*x_6 + 1540*x_7 + 7315*x_8 + 26334*x_9 - 13981010],
     24: [-x_1 - 817190*x_10 - 1144066*x_11 - 1352078*x_12 - 1352078*x_13 - 1144066*x_14 - 817190*x_15 - 490314*x_16 - 245157*x_17 - 100947*x_18 - 33649*x_19 - 23*x_2 - 8855*x_20 - 1771*x_21 - 253*x_22 - 23*x_23 - x_24 - 253*x_3 - 1771*x_4 - 8855*x_5 - 33649*x_6 - 100947*x_7 - 245157*x_8 - 490314*x_9 + 27962030,
      -490314*x_10 - 817190*x_11 - 1144066*x_12 - 1352078*x_13 - 1352078*x_14 - 1144066*x_15 - 817190*x_16 - 490314*x_17 - 245157*x_18 - 100947*x_19 - x_2 - 33649*x_20 - 8855*x_21 - 1771*x_22 - 253*x_23 - 23*x_24 - x_25 - 23*x_3 - 253*x_4 - 1771*x_5 - 8855*x_6 - 33649*x_7 - 100947*x_8 - 245157*x_9 + 27962030,
      -245157*x_10 - 490314*x_11 - 817190*x_12 - 1144066*x_13 - 1352078*x_14 - 1352078*x_15 - 1144066*x_16 - 817190*x_17 - 490314*x_18 - 245157*x_19 - 100947*x_20 - 33649*x_21 - 8855*x_22 - 1771*x_23 - 253*x_24 - 23*x_25 - x_26 - x_3 - 23*x_4 - 253*x_5 - 1771*x_6 - 8855*x_7 - 33649*x_8 - 100947*x_9 + 27962030],
     25: [x_1 + 1307504*x_10 + 1961256*x_11 + 2496144*x_12 + 2704156*x_13 + 2496144*x_14 + 1961256*x_15 + 1307504*x_16 + 735471*x_17 + 346104*x_18 + 134596*x_19 + 24*x_2 + 42504*x_20 + 10626*x_21 + 2024*x_22 + 276*x_23 + 24*x_24 + x_25 + 276*x_3 + 2024*x_4 + 10626*x_5 + 42504*x_6 + 134596*x_7 + 346104*x_8 + 735471*x_9 - 55924050,
      735471*x_10 + 1307504*x_11 + 1961256*x_12 + 2496144*x_13 + 2704156*x_14 + 2496144*x_15 + 1961256*x_16 + 1307504*x_17 + 735471*x_18 + 346104*x_19 + x_2 + 134596*x_20 + 42504*x_21 + 10626*x_22 + 2024*x_23 + 276*x_24 + 24*x_25 + x_26 + 24*x_3 + 276*x_4 + 2024*x_5 + 10626*x_6 + 42504*x_7 + 134596*x_8 + 346104*x_9 - 55924050],
     26: [-x_1 - 2042975*x_10 - 3268760*x_11 - 4457400*x_12 - 5200300*x_13 - 5200300*x_14 - 4457400*x_15 - 3268760*x_16 - 2042975*x_17 - 1081575*x_18 - 480700*x_19 - 25*x_2 - 177100*x_20 - 53130*x_21 - 12650*x_22 - 2300*x_23 - 300*x_24 - 25*x_25 - x_26 - 300*x_3 - 2300*x_4 - 12650*x_5 - 53130*x_6 - 177100*x_7 - 480700*x_8 - 1081575*x_9 + 111848110]}

```python
res = 0
for s in values[1]:
    res += (values[n][0].coeff(s) % p) * s
```

```python
res
```

    4*x_1 + 4*x_26


```python
from sympy import *
from h2_math import *

# Denote that a is a variable in the expression

# Defining a function with name h
class h(Function):
    @classmethod
    def eval(cls, x):
        # Return the rule of the function
        return (x-1)**2+1

for a_vals in solve(h(a)-(1+exp(1)+exp(2)),a):
    # The next line is for use in Markdown
    display(Math(f'a={ latex(a_vals) }.'))
    # print(latex(a_vals))
```

```python
from sympy import *
from h2_math import *

x = symbols('x')

class h(Function):
    @classmethod
    def eval(cls, x):
        # Return the rule of the function
        return eval('(x-1)**2+1')

```

$\displaystyle \left(x - 1\right)^{2} + 1$

```python

```


# 三重積と四重積の証明

吉田勝俊（宇都宮大学）

## 参考情報
- [SymPyで代数演算してみる - Qiita](https://qiita.com/zawawahoge/items/1be137a8147902a5e6cb)
- [Matrices (linear algebra) — SymPy 1.6.2 documentation](https://docs.sympy.org/latest/modules/matrices/matrices.html)

```python
import sympy as sym #数式処理ライブラリ
sym.init_printing() #数式を綺麗に表示する設定
```

## Sympy 変数・関数

```python
x1, x2, x3 = sym.symbols('x_1 x_2 x_3')
y1, y2, y3 = sym.symbols('y_1 y_2 y_3')
z1, z2, z3 = sym.symbols('z_1 z_2 z_3')

xs = sym.Matrix([x1,x2,x3]) #xベクトル
ys = sym.Matrix([y1,y2,y3]) #yベクトル
zs = sym.Matrix([z1,z2,z3]) #zベクトル

xs, ys, zs
```

$\displaystyle \left( \left[\begin{matrix}x_{1}\\x_{2}\\x_{3}\end{matrix}\right], \  \left[\begin{matrix}y_{1}\\y_{2}\\y_{3}\end{matrix}\right], \  \left[\begin{matrix}z_{1}\\z_{2}\\z_{3}\end{matrix}\right]\right)$

```python

```

```python
#判定用のゼロベクトル
zeros = sym.Matrix([0,0,0])

zeros
```

$\displaystyle \left[\begin{matrix}0\\0\\0\end{matrix}\right]$

#### 外積と内積のテスト

```python
xs.cross(ys) #外積
```

$\displaystyle \left[\begin{matrix}x_{2} y_{3} - x_{3} y_{2}\\- x_{1} y_{3} + x_{3} y_{1}\\x_{1} y_{2} - x_{2} y_{1}\end{matrix}\right]$

```python
xs.dot(ys) #内積
```

## (O4) スカラ三重積

```python
left  = xs.dot(ys.cross(zs)) #左辺の式
right = xs.cross(ys).dot(zs) #右辺の式
difference = left-right #差をとる
difference = sym.simplify(difference) #式を整理する

print('Left =')
display(left)

print('Right =')
display(right)

print('Difference =')
display(difference)

#判定結果
if difference == 0:
  print('==> "O4" is True.')
```

## (O5) ベクトル四重積

```python
left  = xs.cross(ys.cross(zs)) #左辺の式
right = xs.dot(zs)*ys - xs.dot(ys)*zs #右辺の式
difference = left-right #差をとる
difference = sym.simplify(difference) #式を整理する

print('Left =')
display(left)

print('Right =')
display(right)

print('Difference =')
display(difference)

#判定結果
if difference == zeros: #上で定義したゼロベクトル
  print('==>"O5" is True.')
```

    Left =

$\displaystyle \left[\begin{matrix}x_{2} \left(y_{1} z_{2} - y_{2} z_{1}\right) - x_{3} \left(- y_{1} z_{3} + y_{3} z_{1}\right)\\- x_{1} \left(y_{1} z_{2} - y_{2} z_{1}\right) + x_{3} \left(y_{2} z_{3} - y_{3} z_{2}\right)\\x_{1} \left(- y_{1} z_{3} + y_{3} z_{1}\right) - x_{2} \left(y_{2} z_{3} - y_{3} z_{2}\right)\end{matrix}\right]$

    Right =

$\displaystyle \left[\begin{matrix}y_{1} \left(x_{1} z_{1} + x_{2} z_{2} + x_{3} z_{3}\right) - z_{1} \left(x_{1} y_{1} + x_{2} y_{2} + x_{3} y_{3}\right)\\y_{2} \left(x_{1} z_{1} + x_{2} z_{2} + x_{3} z_{3}\right) - z_{2} \left(x_{1} y_{1} + x_{2} y_{2} + x_{3} y_{3}\right)\\y_{3} \left(x_{1} z_{1} + x_{2} z_{2} + x_{3} z_{3}\right) - z_{3} \left(x_{1} y_{1} + x_{2} y_{2} + x_{3} y_{3}\right)\end{matrix}\right]$

    Difference =

$\displaystyle \left[\begin{matrix}0\\0\\0\end{matrix}\right]$

    ==>"O5" is True.

## (O6) 名無しの四重積

```python
left  = xs.cross(ys.cross(xs.cross(ys))) #左辺の式
right = ys.cross(xs.cross(xs.cross(ys))) #右辺の式
difference = left-right #差をとる
difference = sym.simplify(difference) #式を整理する

print('Left =')
display(left)

print('Right =')
display(right)

print('Difference =')
display(difference)

#判定結果
if difference == zeros: #上で定義したゼロベクトル
  print('==> "O6" is True.')
```

    Left =

$\displaystyle \left[\begin{matrix}x_{2} \left(y_{1} \left(- x_{1} y_{3} + x_{3} y_{1}\right) - y_{2} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) - x_{3} \left(- y_{1} \left(x_{1} y_{2} - x_{2} y_{1}\right) + y_{3} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right)\\- x_{1} \left(y_{1} \left(- x_{1} y_{3} + x_{3} y_{1}\right) - y_{2} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) + x_{3} \left(y_{2} \left(x_{1} y_{2} - x_{2} y_{1}\right) - y_{3} \left(- x_{1} y_{3} + x_{3} y_{1}\right)\right)\\x_{1} \left(- y_{1} \left(x_{1} y_{2} - x_{2} y_{1}\right) + y_{3} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) - x_{2} \left(y_{2} \left(x_{1} y_{2} - x_{2} y_{1}\right) - y_{3} \left(- x_{1} y_{3} + x_{3} y_{1}\right)\right)\end{matrix}\right]$

    Right =

$\displaystyle \left[\begin{matrix}y_{2} \left(x_{1} \left(- x_{1} y_{3} + x_{3} y_{1}\right) - x_{2} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) - y_{3} \left(- x_{1} \left(x_{1} y_{2} - x_{2} y_{1}\right) + x_{3} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right)\\- y_{1} \left(x_{1} \left(- x_{1} y_{3} + x_{3} y_{1}\right) - x_{2} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) + y_{3} \left(x_{2} \left(x_{1} y_{2} - x_{2} y_{1}\right) - x_{3} \left(- x_{1} y_{3} + x_{3} y_{1}\right)\right)\\y_{1} \left(- x_{1} \left(x_{1} y_{2} - x_{2} y_{1}\right) + x_{3} \left(x_{2} y_{3} - x_{3} y_{2}\right)\right) - y_{2} \left(x_{2} \left(x_{1} y_{2} - x_{2} y_{1}\right) - x_{3} \left(- x_{1} y_{3} + x_{3} y_{1}\right)\right)\end{matrix}\right]$

    Difference =

$\displaystyle \left[\begin{matrix}0\\0\\0\end{matrix}\right]$

    ==> "O6" is True.

```python

```


# A 2D version of the Robot Parking problem

Here is a 2D version of the Robot parking problem. Credits for this implemention to  [Thijs van de Laar](https://biaslab.github.io/member/thijs) and [Burak Ergul](https://biaslab.github.io/member/burak).

```julia
using Random
Random.seed!(87613) # Set random seed

using LinearAlgebra
using PyPlot
using ForneyLab

include("environment_2d.jl") # Include environmental dynamics
include("helpers_2d.jl") # Include helper functions for plotting
include("agent_2d.jl") # Load agent's internal beliefs over external dynamics
;
```

### Build model

We define the state of the robot (at time $k$) as the current orientation and Cartesian coordinates:
\begin{align}
    s_k = (ϕ_k, x_k, y_k)^{T}\,.
\end{align}

The control consists of a change in orientation and subsequent travel distance:
\begin{align}
    u_k = (\Delta\phi_k, r_k)^{T}\,.
\end{align}

The model factorization did not change:
\begin{align}
    p_t(o, s, u) &\propto p(s_{t-1}) \prod_{k=t}^{t+T} p(o_k | s_k)\, p(s_k | s_{k-1}, u_k)\, p(u_k)\, \tilde{p}(o_k)\,.
\end{align}

The specific model assumptions however now include a non-linear transition function $g$:
\begin{align}
    p(s_{t-1}) &= \mathcal{N}(s_{t-1} | m_{s, t-t}, V_{s, t-1})\\
    p(s_k | s_{k-1}, u_k) &= \mathcal{N}(s_k | g(s_{k-1}, u_k), \Gamma^{-1})\\
    p(o_k | s_k) &= \mathcal{N}(o_k | s_k, \Phi^{-1})\\
    p(u_k) &= \mathcal{N}(u_k | 0, \Upsilon) \text{, for } k>t\\
    \tilde{p}(o_k) &= \mathcal{N}(o_k | 0, \Sigma) \text{, for } k>t\\
    p(u_t) &= \delta(u_t - \hat{u}_t)\\
    \tilde{p}(o_t) &= \delta(o_t - \hat{o}_t)\,.
\end{align}

```julia
# Internal model perameters
Gamma   = 100.0*diageye(3) # Transition precision
Phi     = 10.0*diageye(3) # Observation precision
Upsilon = Diagonal([0.25*pi, 1.0].^2) # Control prior variance
Sigma   = Diagonal([1.0, 30.0, 30.0]) # Goal prior variance
;
```

```julia
T = 10 # Lookahead

# Build internal model
fg = FactorGraph()

o   = Vector{Variable}(undef, T) # Observed states
s_g = Vector{Variable}(undef, T) # Noiseless internal states
s   = Vector{Variable}(undef, T) # Noisy internal states
u   = Vector{Variable}(undef, T) # Control states

@RV s_t_min ~ GaussianMeanVariance(placeholder(:m_s_t_min, dims=(3,)),
                                   placeholder(:V_s_t_min, dims=(3,3))) # Prior internal state
u_t = placeholder(:u_t, dims=(2,))
@RV u[1]   ~ GaussianMeanVariance(u_t, tiny*diageye(2))
@RV s_g[1] ~ Nonlinear(s_t_min, u[1], g, g_inv_in1=g_inv_in1, g_inv_in2=g_inv_in2)
@RV s[1]   ~ GaussianMeanPrecision(s_g[1], Gamma)
@RV o[1]   ~ GaussianMeanPrecision(s[1], Phi)
placeholder(o[1], :o_t, dims=(3,))

s_k_min = s[1]
for k=2:T
    @RV u[k]   ~ GaussianMeanVariance(zeros(2), Upsilon)
    @RV s_g[k] ~ Nonlinear(s_k_min, u[k], g, g_inv_in1=g_inv_in1, g_inv_in2=g_inv_in2) # Noiseless transition model
    @RV s[k]   ~ GaussianMeanPrecision(s_g[k], Gamma) # State transition model including noise
    @RV o[k]   ~ GaussianMeanPrecision(s[k], Phi) # Observation model
    GaussianMeanVariance(o[k],
                         placeholder(:m_o, var_id=:m_o_*k, index=k-1, dims=(3,)),
                         placeholder(:V_o, var_id=:V_o_*k, index=k-1, dims=(3,3))) # Goal prior
    s_k_min = s[k]
end
;
```

### Infer algorithm

```julia
# Schedule message passing algorithm
algo = sumProductAlgorithm(u[2]) # Infer internal states
eval(Meta.parse(algo)) # Loads the step!() function for inference
inspectSnippet(algo) # Inspect a snippet of the algorithm code
;
```

    function step!(data::Dict, marginals::Dict=Dict(), messages::Vector{Message}=Array{Message}(undef, 59))

    messages[1] = ruleSPGaussianMeanVarianceOutNPP(nothing, Message(Multivariate, PointMass, m=[0.0, 0.0]), Message(MatrixVariate, PointMass, m=Diagonal([0.6168502750680849, 1.0])))
    messages[2] = ruleSPGaussianMeanVarianceOutNPP(nothing, Message(Multivariate, PointMass, m=data[:m_s_t_min]), Message(MatrixVariate, PointMass, m=data[:V_s_t_min]))
    messages[3] = ruleSPGaussianMeanVarianceOutNPP(nothing, Message(Multivariate, PointMass, m=data[:u_t]), Message(MatrixVariate, PointMass, m=Diagonal([1.0e-12, 1.0e-12])))

    ...

    marginals[:u_2] = messages[1].dist * messages[59].dist

    return marginals

    end

### Execute algorithm

```julia
# Initial state
ϕ_0 = pi # Initial orientation
x_0 = 2.0 # Initial coordinates
y_0 = 3.0
;
```

```julia
N = 20 # Total simulation time

(execute, observe)  = initializeWorld() # Let there be a world
(infer, act, slide) = initializeAgent() # Let there be an agent

# Step through action-perception loop
u_hat = Vector{Vector{Float64}}(undef, N) # Actions
o_hat = Vector{Vector{Float64}}(undef, N) # Observations
for t=1:N
    u_hat[t] = act() # Evoke an action from the agent
               execute(u_hat[t]) # The action influences hidden external states
    o_hat[t] = observe() # Observe the current environmental outcome (update p)
               infer(u_hat[t], o_hat[t]) # Infer beliefs from current model state (update q)
               slide() # Prepare for next iteration
end
;
```

### and plot the position track

```julia
# Plot active inference results
plotTrajectory(u_hat, o_hat)
;
```

```julia

```


```python
%matplotlib inline
```

用 PyTorch 做 神经转换 (Neural Transfer)
==========================================
**原作者**: `Alexis Jacq <https://alexis-jacq.github.io>`_

介绍
------------

欢迎观看! 这篇教程解释了如何实现 Leon A. Gatys, Alexander S. Ecker 和
Matthias Bethge 几位学者发明的
`Neural-Style <https://arxiv.org/abs/1508.06576>`__ 算法 .

题中的神经描述的是什么?
~~~~~~~~~~~~~~~~~~

神经风格, 或者说神经转换是一种算法, 它输入一张内容图像 (例如海龟), 一张风格图像
(例如艺术波浪), 然后返回内容图像的内容, 此时返回的内容像是被艺术风格图像的风格渲染过:

.. figure:: /_static/img/neural-style/neuralstyle.png
   :alt: content1

它是如何工作的?
~~~~~~~~~~~~~~~~~~

原理很简单: 我们定义两个距离, 一个是关于内容的 ($D_C$) , 另一个是关于风格的
($D_S$) . $D_C$ 衡量两张图像的内容有多么不同, 而 $D_S$
衡量两张图像的风格有多么不同. 接着我们拿出我们的输入, 也就是第三张图像 (例如全噪声),
然后我们转换它, 同时最小化它与内容图像的内容距离和它与风格图像的风格距离.

好吧, 它具体是怎么工作的?
^^^^^^^^^^^^^^^^^^^^^^

继续深入需要一些数学知识. 令 $C_{nn}$ 代表一个预训练好的深度卷积神经网络,
$X$ 代表任何图像. $C_{nn}(X)$ 是神经网络输入 $X$ 后的结果
(包括在所有层的特征映射). 令 $F_{XL} \in C_{nn}(X)$ 代表在深度为 $L$
层处的特征映射, 都矢量化和级联为一个单一矢量. 我们简单地用 $F_{XL}$ 定义
$X$ 在 $L$ 层的内容. 如果 $Y$ 是另一张和 $X$ 相同大小的图像,
我们定义这两张图像在 $L$ 层的内容距离如下:

\begin{align}D_C^L(X,Y) = \|F_{XL} - F_{YL}\|^2 = \sum_i (F_{XL}(i) - F_{YL}(i))^2\end{align}

式中 $F_{XL}(i)$ 是 $F_{XL}$ 的第 $i^{th}$ 个元素.
定义风格要更繁琐一些. 令满足 $k \leq K$ 的 $F_{XL}^k$ 代表
$L$ 层矢量化的 $K$ 个特征映射中的第 $k^{th}$ 个.
图像 $X$ 在 $L$ 层的风格 $G_{XL}$ 定义为满足
$k \leq K$ 的所有矢量化特征映射 $F_{XL}^k$ 的克产物 (Gram produce).
换句话说, $G_{XL}$ 是一个 $K$\ x\ $K$ 的矩阵, 其在
$k^{th}$ 行和 $l^{th}$ 列的每个元素 $G_{XL}(k,l)$
是 $F_{XL}^k$ 和 $F_{XL}^l$ 之间的矢量产物 :

\begin{align}G_{XL}(k,l) = \langle F_{XL}^k, F_{XL}^l\rangle = \sum_i F_{XL}^k(i) . F_{XL}^l(i)\end{align}

式中 $F_{XL}^k(i)$ 是 $F_{XL}^k$ 的第 $i^{th}$ 个元素.
我们可以把 $G_{XL}(k,l)$ 当做特征映射 $k$ 和 $l$ 相关性的衡量.
那样的话, $G_{XL}$ 代表了 $X$ 在 $L$ 层特征向量的相关性矩阵.
注意 $G_{XL}$ 的尺寸只决定于特征映射的数量, 不被 $X$ 的尺寸所影响.
然后如果 $Y$ 是 *任意尺寸* 的另一张图像, 我们定义在 $L$ 层的风格距离如下:

\begin{align}D_S^L(X,Y) = \|G_{XL} - G_{YL}\|^2 = \sum_{k,l} (G_{XL}(k,l) - G_{YL}(k,l))^2\end{align}

要想一次性地在一些层最小化一个可变图像 $X$ 与目标内容图像 $C$
间的 $D_C(X,C)$, 和 $X$ 与目标风格图像 $S$ 间的
$D_S(X,S)$ , 我们计算并加和每个目标层每个距离的梯度 (对 $X$ 求导).

\begin{align}\nabla_{	extit{total}}(X,S,C) = \sum_{L_C} w_{CL_C}.\nabla_{	extit{content}}^{L_C}(X,C) + \sum_{L_S} w_{SL_S}.\nabla_{	extit{style}}^{L_S}(X,S)\end{align}

式中 $L_C$ 和 $L_S$ 分别是内容和风格的目标层(任意陈述),
$w_{CL_C}$ 和 $w_{SL_S}$ 是风格和内容关于每个目标层的权重(任意陈述).
然后我们对 $X$ 进行梯度下降:

\begin{align}X \leftarrow X - \alpha \nabla_{	extit{total}}(X,S,C)\end{align}

好吧, 数学的部分就到此为止. 如果你想要更加深入(比如怎么计算梯度),  **我们推荐你阅读原始论文** (作者是 Leon
A. Gatys 和 AL), 论文中这部分解释地更好更清晰.

对于在 PyTorch 中的实现, 我们已经有了我们需要的一切:
事实上就是 PyTorch, 所有的梯度都被为你自动且动态地计算(当你从库中使用函数时).
这就是为什么算法的实现在 PyTorch 中变得非常轻松.

PyTorch 实现
----------------------

如果你不确定是否理解了以上数学公式, 你也可以通过实现它, 在过程中有所领悟.
如果你正在探索 PyTorch , 我们推荐你先阅读这篇教程
:doc:`Introduction to PyTorch </beginner/deep_learning_60min_blitz>`.

包
~~~~~~~~

我们将会依赖下列这些包:

-  ``torch``, ``torch.nn``, ``numpy`` (indispensables packages for
   neural networks with PyTorch)
-  ``torch.autograd.Variable`` (dynamic computation of the gradient wrt
   a variable)
-  ``torch.optim`` (efficient gradient descents)
-  ``PIL``, ``PIL.Image``, ``matplotlib.pyplot`` (load and display
   images)
-  ``torchvision.transforms`` (treat PIL images and transform into torch
   tensors)
-  ``torchvision.models`` (train or load pre-trained models)
-  ``copy`` (to deep copy the models; system package)

```python
from __future__ import print_function

import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.optim as optim

from PIL import Image
import matplotlib.pyplot as plt

import torchvision.transforms as transforms
import torchvision.models as models

import copy
```

Cuda
~~~~

如果你的计算机里有 GPU, 推荐在上面运行算法, 尤其是当你要尝试
大型网络时 (就像 VGG). 有鉴于此, 我们有 ``torch.cuda.is_available()``,
如果你的计算机有可用 GPU 则会返回 True. 然后我们用 ``.cuda()`` 方法
将可分配的进程和模块从 CPU 移动到 GPU. 当我们想将这些模块重新移回 CPU
的时候(比如要用 numpy), 我们用 ``.cpu()`` 方法.
最后, ``.type(dtype)`` 会用来将一个 ``torch.FloatTensor``
转化为 用于 GPU 进程输入的 ``torch.cuda.FloatTensor``.

```python
use_cuda = torch.cuda.is_available()
dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor
```

读取图像
~~~~~~~~~~~

为了简化其实现, 让我们从导入一个相同维度的风格和内容图像开始.
然后我们将它们缩放到想要的输入图像尺寸 (在例子中是 128 和 512,
取决你的 GPU 是否可用) 然后把它们转化为 torch 张量, 以待喂入一个神经网络.

.. Note::
    这里是教程需要的图像的下载链接:
    `picasso.jpg <http://pytorch.org/tutorials/_static/img/neural-style/picasso.jpg>`__ 和
    `dancing.jpg <http://pytorch.org/tutorials/_static/img/neural-style/dancing.jpg>`__.
    下载这两张图像然后把它们加入到名为 ``images`` 的目录中.

```python
# 想要的输出图像尺寸
imsize = 512 if use_cuda else 128  # 如果没有 GPU 则使用小尺寸

loader = transforms.Compose([
    transforms.Scale(imsize),  # 缩放图像
    transforms.ToTensor()])  # 将其转化为 torch 张量

def image_loader(image_name):
    image = Image.open(image_name)
    image = Variable(loader(image))
    # 由于神经网络输入的需要, 添加 batch 的维度
    image = image.unsqueeze(0)
    return image

style_img = image_loader("images/picasso.jpg").type(dtype)
content_img = image_loader("images/dancing.jpg").type(dtype)

assert style_img.size() == content_img.size(), \
    "we need to import style and content images of the same size"
```

导入的 PIL 图像像素值的范围为 0 到 255. 转化为 torch 张量后,
它们的值范围变为了 0 到and 1. 这是个重要的细节:
torch 库中的神经网络被使用 0-1 的张量图像训练. 如果你尝试用
0-255 的张量图像喂入神经网络, 激活的特征映射就没用了. 这不是
使用 Caffe 库中预训练的神经网络, Caffe 中是用 0-255 的张量图像训练的.

显示图像
~~~~~~~~~~~~~~

我们将使用 ``plt.imshow`` 来显示图像.
所以我们需要先把它们转回 PIL 图像.

```python
unloader = transforms.ToPILImage()  # 转回 PIL 图像

plt.ion()

def imshow(tensor, title=None):
    image = tensor.clone().cpu()  # 克隆是为了不改变它
    image = image.view(3, imsize, imsize)  # 移除 batch 维度
    image = unloader(image)
    plt.imshow(image)
    if title is not None:
        plt.title(title)
    plt.pause(0.001) # 暂停一会, 让绘图更新

plt.figure()
imshow(style_img.data, title='Style Image')

plt.figure()
imshow(content_img.data, title='Content Image')
```

内容损失
~~~~~~~~~~~~

内容损失是一个在网络输入为 $X$ 的层 $L$ 输入特征映射
$F_{XL}$ 的函数, 返回此图像与内容图像间的加权内容距离
$w_{CL}.D_C^L(X,C)$. 之后, 权重 $w_{CL}$ 和目标内容
$F_{CL}$ 就成为了函数的参数. 我们把这个函数作为 torch 模块来实现, 把这些参
数作为构造器的输入. 这个距离 $\|F_{XL} - F_{YL}\|^2$ 是两个特征映射集的
均方误差, 可以用作为第三个参数的标准的 ``nn.MSELoss`` 来计算.

我们会在每个目标层加入我们的内容损失作为额外的神经网络模块. 这样, 每次我们都会给神经
网络投喂一张输入图像 $X$, 所有的损失都会在目标层被计算, 多亏了自动梯度计算,
所有梯度都会被搞定. 要实现, 我们只需写出转换模块的 ``forward`` 方法, 这个模块就变
成了网络的 ''transparent layer (透明层)'', 计算好的损失被存为模块的参数.

最后, 我们定义一个假的 ``backward`` 方法, 它仅仅只调用后向方法 ``nn.MSELoss``
来重构梯度.
这个方法返回计算好的损失: 运行梯度下降时要想显示风格和内容损失的变化, 这会非常有用.

```python
class ContentLoss(nn.Module):

    def __init__(self, target, weight):
        super(ContentLoss, self).__init__()
        # 我们会从所使用的树中“分离”目标内容
        self.target = target.detach() * weight
        # 动态地计算梯度: 它是个状态值, 不是变量.
        # 否则评价指标的前向方法会抛出错误.
        self.weight = weight
        self.criterion = nn.MSELoss()

    def forward(self, input):
        self.loss = self.criterion(input * self.weight, self.target)
        self.output = input
        return self.output

    def backward(self, retain_graph=True):
        self.loss.backward(retain_graph=retain_graph)
        return self.loss
```

.. Note::
   **重要细节**: 这个模块虽然叫做 ``ContentLoss``, 却不是个真正的 Pytorch
   损失函数. 如果你想像 Pytorch 损失一样定义你的内容损失, 你得新建一个 Pytorch
   自动求导函数并手动得在 ``backward`` 方法中重算/实现梯度.

风格损失
~~~~~~~~~~

对于风格损失, 我们首先需要定义一个给定输入 $X$ 在 $L$
层的特征映射 $F_{XL}$ 时计算克产物 $G_{XL}$ 的模块. 令
$\hat{F}_{XL}$ 表示 $F_{XL}$ 重变形为
$K$\ x\ $N$ 的版本, 这里 $K$ 是 $L$ 层特征
映射的数量, $N$ 是任意矢量化特征映射 $F_{XL}^k$ 的长度.
$\hat{F}_{XL}$ 的第 $k^{th}$ 行是 $F_{XL}^k$.
可以验证 $\hat{F}_{XL} \cdot \hat{F}_{XL}^T = G_{XL}$. 鉴于此,
实现我们的模块就很容易了:

```python
class GramMatrix(nn.Module):

    def forward(self, input):
        a, b, c, d = input.size()  # a=batch size(=1)
        # b= 特征映射的数量
        # (c,d)= 一个特征映射的维度 (N=c*d)

        features = input.view(a * b, c * d)  # 将 F_XL 转换为 \hat F_XL

        G = torch.mm(features, features.t())  # 计算克产物 (gram product)

        # 我们用除以每个特征映射元素数量的方法
		# 标准化克矩阵 (gram matrix) 的值
        return G.div(a * b * c * d)
```

特征映射的维度 $N$ 越长, 则克矩阵 (gram matrix) 的值越大.
因此如果我们不用 $N$ 来标准化, 在梯度下降过程中第一层
(在池化层之前) 的损失计算就会过于重要. 我们当然不希望这样,
因为我们感兴趣的风格特征都在最深的那些层!

接着, 风格损失模块被以和内容损失模块相同的方式实现,
但是我们还得把 ``gramMatrix`` 加入作为参数:

```python
class StyleLoss(nn.Module):

    def __init__(self, target, weight):
        super(StyleLoss, self).__init__()
        self.target = target.detach() * weight
        self.weight = weight
        self.gram = GramMatrix()
        self.criterion = nn.MSELoss()

    def forward(self, input):
        self.output = input.clone()
        self.G = self.gram(input)
        self.G.mul_(self.weight)
        self.loss = self.criterion(self.G, self.target)
        return self.output

    def backward(self, retain_graph=True):
        self.loss.backward(retain_graph=retain_graph)
        return self.loss
```

读取神经网络
~~~~~~~~~~~~~~~~~~~~~~~

现在, 我们要导入一个预训练好的神经网络. 和论文一样, 我们用预训练
的 19 层 VGG 网络 (VGG19).

PyTorch对 VGG 的实现模块分为两个子 ``Sequential`` 模块:
``features`` (包括卷积和池化层) 和 ``classifier`` (包括全连接层).
我们只对 ``features`` 感兴趣:

```python
cnn = models.vgg19(pretrained=True).features

# 可能的话将它移到 GPU 上:
if use_cuda:
    cnn = cnn.cuda()
```

``Sequential`` (顺序) 模块包含一个子模块的列表. 比如,
``vgg19.features`` 包含一个以正确深度排列的序列 (Conv2d, ReLU,
Maxpool2d, Conv2d, ReLU...), 就如我们在 *Content loss* 部分讲到的,
我们想要把我们的风格和内容损失模块以想要的深度作为 '透明层' 加入到
我们的网络中. 为了这样, 我们建立了一个新的 ``Sequential`` (顺序)
模块, 在其中我们把 ``vgg19`` 和我们的损失模块以正确的顺序加入:

```python
# 希望计算风格/内容损失的层 :
content_layers_default = ['conv_4']
style_layers_default = ['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5']

def get_style_model_and_losses(cnn, style_img, content_img,
                               style_weight=1000, content_weight=1,
                               content_layers=content_layers_default,
                               style_layers=style_layers_default):
    cnn = copy.deepcopy(cnn)

    # 仅为了有一个可迭代的列表 内容/风格 损失
    content_losses = []
    style_losses = []

    model = nn.Sequential()  # 新建的 Sequential 网络模块
    gram = GramMatrix()  # 我们需要一个克模块 (gram module) 来计算风格目标

    # 可能的话将这些模块移到 GPU 上:
    if use_cuda:
        model = model.cuda()
        gram = gram.cuda()

    i = 1
    for layer in list(cnn):
        if isinstance(layer, nn.Conv2d):
            name = "conv_" + str(i)
            model.add_module(name, layer)

            if name in content_layers:
                # 加内容损失:
                target = model(content_img).clone()
                content_loss = ContentLoss(target, content_weight)
                model.add_module("content_loss_" + str(i), content_loss)
                content_losses.append(content_loss)

            if name in style_layers:
                # 加风格损失:
                target_feature = model(style_img).clone()
                target_feature_gram = gram(target_feature)
                style_loss = StyleLoss(target_feature_gram, style_weight)
                model.add_module("style_loss_" + str(i), style_loss)
                style_losses.append(style_loss)

        if isinstance(layer, nn.ReLU):
            name = "relu_" + str(i)
            model.add_module(name, layer)

            if name in content_layers:
                # 加内容损失:
                target = model(content_img).clone()
                content_loss = ContentLoss(target, content_weight)
                model.add_module("content_loss_" + str(i), content_loss)
                content_losses.append(content_loss)

            if name in style_layers:
                # 加风格损失:
                target_feature = model(style_img).clone()
                target_feature_gram = gram(target_feature)
                style_loss = StyleLoss(target_feature_gram, style_weight)
                model.add_module("style_loss_" + str(i), style_loss)
                style_losses.append(style_loss)

            i += 1

        if isinstance(layer, nn.MaxPool2d):
            name = "pool_" + str(i)
            model.add_module(name, layer)  # ***

    return model, style_losses, content_losses
```

.. Note::
   在这篇论文中他们推荐将最大池化层更改为平均池化层.
   AlexNet是一个比 VGG19 更小的网络, 用它实现的话我们也不会看到
   任何结果质量的不同. 而如果你想做这个替代的话, 可以用这些代码:

   ::

       # avgpool = nn.AvgPool2d(kernel_size=layer.kernel_size,
       #                         stride=layer.stride, padding = layer.padding)
       # model.add_module(name,avgpool)

输入图像
~~~~~~~~~~~

为了简化代码, 我们用与内容和风格图像同样尺寸的图像做输入.
这个图像可以是白噪声的, 也可以是一份内容图像的拷贝.

```python
input_img = content_img.clone()
# 如果你想用白噪声做输入, 请取消下面的注释行:
# input_img = Variable(torch.randn(content_img.data.size())).type(dtype)

# 在绘图中加入原始的输入图像:
plt.figure()
imshow(input_img.data, title='Input Image')
```

梯度下降
~~~~~~~~~~~~~~~~

由于本算法的作者 Leon Gatys 的建议
`here <https://discuss.pytorch.org/t/pytorch-tutorial-for-neural-transfert-of-artistic-style/336/20?u=alexis-jacq>`__,
我们将使用 L-BFGS 算法来跑我们的梯度下降. 和训练一个网络不同的是,
我们希望训练输入图像来最小化 内容/风格 损失. 我们想简单地建一个
PyTorch L-BFGS 优化器, 传入我们的图像作为变量进行优化.
但是 ``optim.LBFGS`` 的第一个形参是一个需要梯度的 PyTorch ``Variable`` .
我们的输入图像是一个 ``Variable`` , 但不是需要计算梯度的树的叶节点.
为了使这个变量需要梯度运算, 一个可能的方法是从输入图像构建一个
``Parameter`` (参数) 对象. 然后我们只需给优化器的构造器传递一个
包含这个参数的列表:

```python
def get_input_param_optimizer(input_img):
    # 这行显示了输入是一个需要梯度计算的参数
    input_param = nn.Parameter(input_img.data)
    optimizer = optim.LBFGS([input_param])
    return input_param, optimizer
```

**最后一步**: 循环进行梯度下降. 每一步中我们必须喂给神经网络更新后
的输入以计算新的损失, 我们要运行每个损失的 ``backward`` 方法来动态
计算他们的梯度并呈现梯度下降的每一步. 这个优化器需要一个 "closure"
: 一个重新评估模型并返回损失的函数.

然而, 这里有一个小问题. 被优化的图像的像素值会在 $-\infty$
和 $+\infty$ 之间波动, 而不是继续保持在 0 到 1. 换句话说,
图像可能会被完美地优化成荒谬的值. 事实上, 我们必须在限制下使用
优化器来使我们的输入图像一直保持正确的值. 有一个简单的解决方案:
在每一步, 都校正图像使其保持 0-1 范围的值.

```python
def run_style_transfer(cnn, content_img, style_img, input_img, num_steps=300,
                       style_weight=1000, content_weight=1):
    """Run the style transfer."""
    print('Building the style transfer model..')
    model, style_losses, content_losses = get_style_model_and_losses(cnn,
        style_img, content_img, style_weight, content_weight)
    input_param, optimizer = get_input_param_optimizer(input_img)

    print('Optimizing..')
    run = [0]
    while run[0] <= num_steps:

        def closure():
            # 校正更新后的输入图像值
            input_param.data.clamp_(0, 1)

            optimizer.zero_grad()
            model(input_param)
            style_score = 0
            content_score = 0

            for sl in style_losses:
                style_score += sl.backward()
            for cl in content_losses:
                content_score += cl.backward()

            run[0] += 1
            if run[0] % 50 == 0:
                print("run {}:".format(run))
                print('Style Loss : {:4f} Content Loss: {:4f}'.format(
                    style_score.data[0], content_score.data[0]))
                print()

            return style_score + content_score

        optimizer.step(closure)

    # 最后一次的校正...
    input_param.data.clamp_(0, 1)

    return input_param.data
```

最后, 运行算法

```python
output = run_style_transfer(cnn, content_img, style_img, input_img)

plt.figure()
imshow(output, title='Output Image')

# sphinx_gallery_thumbnail_number = 4
plt.ioff()
plt.show()
```


Table of Contents

1  Getting Started

1.1  References

2  Extended Kalman Filter

2.1  EKF Theory

2.1.1  State variables

2.1.2  System model (Prediction step)

2.1.2.1  System model linearization

2.1.2.2  System model noise

2.1.3  Measurement model (Update step)

2.1.3.1  Measurement model linearization

2.1.3.2  Measurement model noise

2.1.4  Process flow

2.1.4.1  PREDICTION

2.1.4.2  CORRECTION (Update)

2.2  EKF Implementation

2.2.1  EXAMPLE 1

2.2.1.1  PLOT example1 with choosen simulated parameters

Tip: This notebook uses nbextension TOC, enable it installing pip install jupyter-contrib-nbextensions.

# Getting Started

This Notebook contains a brief theory and practical Python tests with the Extended Kalman Filter algorithm.

>**Author:** Iñaki Lorente

## References

1. Introduction to Autonomous Mobile Robots by Roland Siegwart, Illah Reza Nourbakhs and Davide Scaramuzza, MIT Press.
2. Probabilistic Robotics by Sebastian Thrun, Wolfram Burgard and Dieter Fox, MIT Press.http://www.probabilistic-robotics.org/
3. Atsushi Sakai project. PythonRobotics, https://atsushisakai.github.io/PythonRobotics/
4. Paul Balzer Kalman documentation, https://github.com/balzer82/Kalman
5. Kalman and Bayesian Filters in Python. Roger R Labbe Jr. https://drive.google.com/file/d/0By_SW19c1BfhSVFzNHc0SjduNzg/view

# Extended Kalman Filter

## EKF Theory

This is just an introduction of the EKF basics. All info can be studied in more detail using the references.

### State variables

Depending on the robot characteristics define the **State vector** with the correct number of states. This example shows only 3 states.
In this simple case we maintain the position x, y and orientation $\theta$ of the robot:

$$x = \begin{bmatrix} x \\ y \\ \theta \end{bmatrix}$$

The control input $u$ is the velocity $v$ and steering angle $\alpha$

$$u = \begin{bmatrix} v \\ \alpha \end{bmatrix}$$

Where:

   - $x$ and $y$ : 2D coordenates
   - $u$ : Input ($u = [v, \alpha]$, where $v$ is the velocity and $\alpha$ the angle)
   - $\theta$ : Orientation

### System model (Prediction step)

Using the EKF the system model is a nonlinear motion model plus noise.

$$x_t = g(x_{t-1}, u_t) + \epsilon_t$$

Where:

   - $g$ : Non-linear function over the state vector at time $t$. Can be used to compute the predicted state from the previous estimate
   - $u_t$ : Input ($u_t = [v, \alpha]$, where $v$ is the velocity and $w$ the gyro)
   - $x_{t-1}$ : Previous state
   - $\epsilon_t$ : Process noise at time $t$

Let $x_{t-1} = (x,y,\theta)^T$ be the initial pose of the robot, and suppose we keep the velocity constant at $(v, \alpha)^T$ for some time $\Delta_t$.

The center of the circle is then:

$$x_c = x - \frac{v}{\alpha}sin(\theta)$$

$$y_c = y + \frac{v}{\alpha}cos(\theta)$$

After $\Delta_t$ time of motion, our ideal robot will be at $x_t = (x', y', \theta')^T$ with:

$\begin{bmatrix}x'\\y'\\\theta' \end{bmatrix} = \begin{bmatrix} x_c + \frac{v}{\alpha}sin(\theta + \alpha \Delta_t)\\y_c - \frac{v}{\alpha}cos(\theta + \alpha \Delta_t)\\\theta + \alpha \Delta_t\end{bmatrix} = \begin{bmatrix}x\\y\\\theta \end{bmatrix} +
\begin{bmatrix} -\frac{v}{\alpha}sin(\theta) + \frac{v}{\alpha}sin(\theta + \alpha \Delta_t)\\\frac{v}{\alpha}cos(\theta) - \frac{v}{\alpha}cos(\theta + \alpha \Delta_t)\\ \alpha \Delta_t\end{bmatrix}$

>To compute the kinematics with non-constant velocities, it is therefore common practice to use small values for $\Delta_t$, and to approximate
the actual velocity by a constant within each time interval.

#### System model linearization

>$g$ cannot be applied to the covariance directly. A matrix of partial derivates (The Jacobian matrix) is computed.

At each time step, the Jacobian is evaluated with current predicted states. **This process linearizes the non-linear function $g$ around the current estimate**.

From the Robot motion formulation exposed before, we can get the **motion model**:

$$x_t = \begin{bmatrix}x\\y\\\theta \end{bmatrix} +
\begin{bmatrix} -\frac{v}{\alpha}sin(\theta) + \frac{v}{\alpha}sin(\theta + \alpha\Delta_t)\\\frac{v}{\alpha}cos(\theta) - \frac{v}{\alpha}cos(\theta + \alpha\Delta_t)\\ \alpha\Delta_t\end{bmatrix}$$

Its Jacobian is:

$G_t = \begin{bmatrix} 1 & 0 & -\frac{v_t}{\alpha_t}cos(\theta) + \frac{v_t}{\alpha_t}cos(\theta + \alpha_t\Delta_t)\\0 & 1 & -\frac{v_t}{\alpha_t}sin(\theta) + \frac{v_t}{\alpha_t}sin(\theta + \alpha \Delta_t)\\ 0 & 0 & 1\end{bmatrix}$

#### System model noise

We command a specific velocity and steering angle (using $u$), but we need to convert that into errors in $x, y, \theta$. It vary depending on velocity, so it will need to be recomputed for every prediction.

$$M_t = \begin{bmatrix}
        \alpha_1 v²_t + \alpha_2 \alpha²_t & 0 \\
        0 & \alpha_3 v²_t + \alpha_4 \alpha²_t
        \end{bmatrix}$$

The transformation from control space to state space is performed by another linear approximation. The Jacobian needed for this approximation, denoted $V_t$ is the derivate of the motion function $g$ with respect to the motion parameters, evaluated at $u_t$ and $u_{t-1}$

$$V_t = \frac{\partial g(u_t, u_{t-1})}{\partial u_t} = \begin{bmatrix}
\frac{\partial x'}{\partial v_t} & \frac{\partial x'}{\partial \alpha_t} \\
\frac{\partial y'}{\partial v_t} & \frac{\partial y'}{\partial \alpha_t} \\
\frac{\partial \theta'}{\partial v_t} & \frac{\partial \theta'}{\partial \alpha_t} \\
\end{bmatrix} =
\begin{bmatrix}
\frac{-sin \theta + sin(\theta + \alpha_t \Delta_t)}{\alpha_t} &
\frac{v_t(sin \theta - sin(\theta + \alpha_t \Delta_t))}{\alpha²_t} +
\frac{v_t(cos(\theta + \alpha_t \Delta_t)\Delta_t}{\alpha_t} \\
\frac{cos \theta - cos(\theta + \alpha_t \Delta_t)}{\alpha_t} &
-\frac{v_t(cos \theta - cos(\theta + \alpha_t \Delta_t))}{\alpha²_t} +
\frac{v_t(sin(\theta + \alpha_t \Delta_t)\Delta_t}{\alpha_t} \\
0 & \Delta_t
\end{bmatrix}
$$

The multiplication $V_t M_t V_t^T$ then provides an approximate mapping between the motion noise in control space to the motion noise in state space.

$$R_t = V_t M_t V_t^T$$

Using $R_t$ and $G_t$ we can get the error covariance ahead:

$$P_{t+1} = G_t P_{t-1} G_t^T + R_t$$

We have finished then the Prediction step.
For a real problem you have to carefully model your system with differential equations and then determine the most appropriate way to solve that system. The correct approach depends on the accuracy you require, how nonlinear the equations are, your processor budget, and numerical stability concerns.

### Measurement model (Update step)

The robot's sensor provides a noisy bearing and range measurement to multiple known locations in the landscape. The measurement model must convert the state $[xyθ]^T$ into a range and bearing to the landmark. If $p$ is the position of a landmark, the range $r$ is

$$r = \sqrt{(p_x - x)^2+(p_y - y)^2}$$

The sensor provides bering relative to the orientation of the robot:

$$\phi = arctan(\frac{p_y - y}{px - x}) - \theta$$

$$z_t = \begin{bmatrix} x \\ y \\ \theta \end{bmatrix}$$

$$z_t = h(x_t) + \delta_t =
\begin{bmatrix}
\sqrt{(p_x - x)^2+(p_y - y)^2} \\
arctan(\frac{p_y - y}{px - x}) - \theta
\end{bmatrix} + \delta_t
$$

Where:

   - $h$ : Non-linear function over the state vector at time $t$. Can be used to compute the predicted mesurement from the predicted state
   - $\delta_t$ : Observation noise at time $t$
   - $p$ : Position of a landmark
   - $r$ : range mesurement
   - $\phi$ : Bearing or heading direction

#### Measurement model linearization

Same way we did at State model part with function $g$, here we need to linearize the nonlineal function $h$

$$H_t = \frac{\partial h(\hat{x},p)}{\partial x_t} =
\begin{bmatrix}
\frac{-p_x + x}{\sqrt{(p_x - x)^2+(p_y - y)^2}} &
\frac{-p_y + y}{\sqrt{(p_x - x)^2+(p_y - y)^2}} & 0 \\
\frac{-p_y + y}{\sqrt{(p_x - x)^2+(p_y - y)^2}} &
-\frac{p_x + x}{\sqrt{(p_x - x)^2+(p_y - y)^2}} & -1
\end{bmatrix}$$

#### Measurement model noise

Additional mesurement noise from the previous measurement state:

$$Q_t = \begin{bmatrix}
\sigma_x^2 & 0 & 0 \\
 0 & \sigma_y^2 & 0 \\
 0 & 0 & \sigma_\phi^2
\end{bmatrix}$$

###  Process flow

#### PREDICTION

Project the state vector ahead :

$$x_{t+1} = g(x_t, u)$$

Project the error covariance ahead:

$$P_{t+1} = G_t P_{t-1} G_t^T + R_t$$

#### CORRECTION (Update)

Compute the Kalman Gain :

$$K_t = P_t H_t^T (H_t P_t H_t^T + Q_t)^-1$$

Update the estimate via mesurement :

$$x_t = x_t + K_t (z_t - h(x_t))$$

Update the error covariance :

$$P_t = (1-K_t H_t) P_t$$

Where:

- $K_t$ : Kalman Gain
- $P_t$ : Covariance matrix of the state at time t
- $Q_t$ : Covariance matrix of measurement noise at time t
- $R_t$ : Covariance matrix of system noise at time t
- $G_t$ : Jacobian of system function at time t
- $H_t$ : Jacobian of measurement function at time

## EKF Implementation

```python
import math
import numpy as np
import sympy

class EKF():

    def __init__(self, dt, wheelbase):

        # Dimensions
        dim_x = 3
        dim_z = 2

        #######################
        # 0. INIT
        #######################
        self.dt = dt
        self.wheelbase = wheelbase

        self.x = np.zeros((dim_x,1))        # True trajectory state
        self.P = np.eye(dim_x)              # uncertainty covariance
        self.G = np.eye(dim_x)              # state transition matrix
        self.R = np.eye(dim_z)              # state uncertainty
        self.Q = np.eye(dim_x)              # process uncertainty

        self.K = np.zeros(self.x.shape)     # kalman gain
        self.S = np.zeros((dim_z, dim_z))   # system uncertainty
        self.y = np.zeros((dim_z, 1))       # residual
        self.I = np.eye(dim_x)              # identity matrix

        self.x_est = self.x                 # Estimated trajectory state

        ##################################
        # 1. FORUMLAS: Get sympy symbols
        ##################################
        x, y, theta, v, a, w, t, lx, ly = sympy.symbols('x, y, theta, v, a, w, t, lx, ly')

        # Get wheel information
        dist = v*t # distance
        beta = (dist/w)*sympy.tan(a) # (distance/wheelbase) * steering angle
        r  = w/sympy.tan(a) # radius

        ###################
        # 1.1 System model
        ###################

        # state = [x,y,theta] (pos_x, pos_y, yaw_rate)
        self.state_formula = sympy.Matrix([x,y,theta])

        # motion = [v,a] (velocity, steering angle)
        self.motion_formula = sympy.Matrix([v,a])

        # g = Non-linear function over the state vector at time t (predicted state)
        self.g_formula = sympy.Matrix([[x-beta*sympy.sin(theta)+r*sympy.sin(theta + beta)],
                          [y+r*sympy.cos(theta)-r*sympy.cos(theta + beta)],
                          [theta+beta]
                         ])

        # Jacobian of g evaluated using state
        self.G_formula = self.g_formula.jacobian(self.state_formula)

        # Jacobian of g evaluated using motion
        self.V_formula = self.g_formula.jacobian(self.motion_formula)

        ########################
        # 1.2 Measurement model
        ########################

        # It depends on the measurement sensor used
        # this case sensor provides noise bearing and range
        # based on landmarks

        # range
        r = sympy.sqrt((lx-x)**2 + (ly-y)**2)
        # bearing
        b = sympy.atan((ly-y)/(lx-x))

        # h = Non-linear function over the state vector at time t (predicted mesurement)
        self.h_formula = sympy.Matrix([[r],
                               [b-theta]
                              ])

        # Jacobian of h evaluated using state
        self.H_formula = self.h_formula.jacobian(self.state_formula)

        ##################################
        # 2. Save values in a dictionary
        ##################################
        self.ekf_dict = {x: 0, y: 0, theta:0,
                         v:0, a:0,
                         t:dt, w:wheelbase}

        # This just creates a link to the dictionay keys
        # the value of the following variables are just
        # names (dictionary key names)
        self.x_x, self.x_y, self.theta = x, y, theta
        self.v, self.a = v, a

    def __repr__(self):
        return '\n'.join([
            'Extended Kalman Filter object',
            '------------------------------',
            'x: ', str(self.x),
            'P: ', str(self.P),
            'x_prior: ', str(self.x_prior),
            'P_prior', str(self.P_prior),
            'G: ', str(self.G),
            'Q: ', str(self.Q),
            'R: ', str(self.R),
            'K: ', str(self.K),
            'y: ', str(self.y),
            'S: ', str(self.S)
            ])

    def predict(self, u):
        '''EKF Prediction step
                input  -> u = motion control [v,a]
                call   -> move function
                action -> get P based on new values
        '''
        # Write values on EKF dictionary
        self.ekf_dict[self.x_x] = self.x[0,0]
        self.ekf_dict[self.x_y] = self.x[1,0]
        self.ekf_dict[self.theta] = self.x[2,0]
        self.ekf_dict[self.v] = u[0]
        self.ekf_dict[self.a] = u[1]

        # Get G,V values applying dicctionary values to formulas
        self.G = np.array(self.G_formula.evalf(subs=self.ekf_dict)).astype(float)
        self.V = np.array(self.V_formula.evalf(subs=self.ekf_dict)).astype(float)

        # M = Covariance of motion noise
        self.M = np.array([[u[0]**2, 0],
                           [0, u[1]**2]
                          ])

        self.Q = np.dot(self.V, self.M).dot(self.V.T)

        # P = Error covariance
        self.P = np.dot(self.G, self.P).dot(self.G.T) + self.Q

    def update(self, landmark, std_range, std_bearing):
        '''EKF Update step based on landmarks
                input  -> landmarks, sensor range and bearing
                action -> update P and state (x) based on measurements
        '''
        for lmark in landmark:
            hyp = (lmark[0] - self.x[0, 0])**2 + (lmark[1] - self.x[1, 0])**2
            dist = math.sqrt(hyp)

            # Get measurement h on last current state
            # This state (x) has predictions applied
            self.h = np.array([[dist],
                               [math.atan2(lmark[1] - self.x[1, 0], lmark[0] - self.x[0, 0]) - self.x[2, 0]]
                              ])

            # Get jacobian of h on last current state
            # This state (x) has predictions applied
            self.H = np.array([[-(lmark[0] - self.x[0, 0]) / dist, -(lmark[1] - self.x[1, 0]) / dist, 0],
                               [(lmark[1] - self.x[1, 0]) / hyp,  -(lmark[0] - self.x[0, 0]) / hyp, -1]
                              ])

            # Get measurement based on true state (x)
            # This state (x) is prior to predictions
            x, y = self.x[0, 0], self.x[1, 0]
            d = math.sqrt((lmark[0] - x)**2 + (lmark[1] - y)**2)
            a = math.atan2(lmark[1] - y, lmark[0] - x) - self.x[2, 0]
            self.z = np.array([[d + np.random.randn()*std_range],
                               [a + np.random.randn()*std_bearing]
                              ])

            # Covariance of measurement noise
            self.R = np.diag([std_range**2, std_bearing**2])

            # K = Kalman Gain
            PHT = np.dot(self.P, self.H.T)
            self.S = np.dot(self.H,PHT) + self.R
            self.K = PHT.dot(np.linalg.inv(self.S))

            # Update the estimate via mesurement (state)
            self.y = self.residual(self.z, self.h)
            self.x_est = self.x + np.dot(self.K, self.y)

            # Update Error covariance (P)
            self.P = (self.I - np.dot(self.K,self.H)).dot(self.P)
            #I_KH = self.I - np.dot(self.K, self.H)
            #self.P = np.dot(I_KH, self.P).dot(I_KH.T) + np.dot(self.K, self.R).dot(self.K.T)

        return self.x_est, self.P

    def residual(self, a, b):
        """ compute residual (a-b) between measurements containing
        [range, bearing]. Bearing is normalized to [-pi, pi)"""
        y = a - b
        y[1,0] = y[1,0] % (2 * np.pi)    # force in range [0, 2 pi)
        if y[1,0] > np.pi:               # move to [-pi, pi)
            y[1,0] -= 2 * np.pi
        return y

    def move(self, x, u, dt):
        '''SIM ROBOT MOVEMENT. To be used if we don't have odometry
           from robot. This function is mainly used for
           test purposes.
        '''
        theta = x[2, 0] # x = [x, y, theta] where 'theta' is the steer angle
        vel = u[0]      # u = [v, a] -> get velocity
        steering_angle = u[1] # u = [v, a] -> get steer angle
        dist = vel * dt # distance

        if abs(steering_angle) > 0.001: # is robot turning?
            beta = (dist / self.wheelbase) * math.tan(steering_angle)
            r = self.wheelbase / math.tan(steering_angle) # radius

            dx = np.array([[-r*math.sin(theta) + r*math.sin(theta + beta)],
                           [r*math.cos(theta) - r*math.cos(theta + beta)],
                           [beta]])
        else: # moving in straight line
            dx = np.array([[dist*cos(theta)],
                           [dist*sin(theta)],
                           [theta]])

        # Update current state
        self.x = x + dx

        return self.x

    def plot_covariance_ellipse(self, xEst, PEst):
        ''' Just a way to plot P covariance
        based on https://github.com/AtsushiSakai/PythonRobotics
        '''
        Pxy = PEst[0:2, 0:2]
        eigval, eigvec = np.linalg.eig(Pxy)

        if eigval[0] >= eigval[1]:
            bigind = 0
            smallind = 1
        else:
            bigind = 1
            smallind = 0

        t = np.arange(0, 2 * math.pi + 0.1, 0.1)
        a = math.sqrt(eigval[bigind])
        b = math.sqrt(eigval[smallind])
        x = [a * math.cos(it) for it in t]
        y = [b * math.sin(it) for it in t]
        angle = math.atan2(eigvec[bigind, 1], eigvec[bigind, 0])
        R = np.array([[math.cos(angle), math.sin(angle)],
                      [-math.sin(angle), math.cos(angle)]])
        fx = R.dot(np.array([[x, y]]))
        px = np.array(fx[0, :] + xEst[0, 0]).flatten()
        py = np.array(fx[1, :] + xEst[1, 0]).flatten()

        #plt.plot(px, py, "--g")

        return px, py
```

### EXAMPLE 1

```python
###############################################################
# Instantiate EKF with
#    - initial state x -> [x,y,theta]
#    - sample rate -> dt  (hz, i.e -> 1.0/50.0 = 50 Hz)
#    - wheelbase
#    - velocity
#    - steer_angle
###############################################################

def example1():
    #############
    # INIT
    #############
    ekf = EKF(dt=1.0,
              wheelbase=0.5)

    return ekf
```

#### PLOT example1 with choosen simulated parameters

```python
import matplotlib.pyplot as plt

def run_simulation(start_pos, u, std_range, std_bearing, landmarks):

    ekf = example1()   #USE EXAMPLE1

    ################
    # Plot Variables
    ################
    prediction_step=10
    sim_pos = start_pos.copy()
    track = []
    estimated = []
    covariance = []

    ################
    # Start example
    ################
    for i in range(200):
        sim_pos = ekf.move(sim_pos, u, 1.0/10.) # start simulation, move robot
        track.append(sim_pos)

        # Apply EKF every 'prediction_step' times
        if i % prediction_step == 0:
            ekf.predict(u)
            estimated_ = ekf.update(landmarks, std_range, std_bearing)
            estimated.append(estimated_[0])
            covariance.append([estimated_[0], estimated_[1]])

    ################
    # PLOT EXAMPLE
    ################

    # Plot landmarks
    plt.figure()
    plt.scatter(landmarks[:, 0], landmarks[:, 1], marker='s', s=60, label='Landmarks')

    # Plot track (True trajectory)
    track = np.array(track)
    plt.plot(track[:, 0], track[:,1], color='k', linewidth =2, label='True trajectory')

    # Plot estimated (Estimated trajectory)
    estimated = np.array(estimated)
    plt.plot(estimated[:, 0], estimated[:, 1], color='r', linewidth =2, label='Estimated trajectory')

    # Plot covariance matrix estimation
    label_added =False
    for element in covariance:
        c = ekf.plot_covariance_ellipse(element[0], element[1])
        if not label_added:
            plt.plot(c[0], c[1], '--g', label='Covariance matrix')
            label_added = True
        else:
            plt.plot(c[0], c[1], '--g')

    # Plot general options

    plt.legend()
    plt.axis('equal')
    plt.title("EKF Robot localization")
    plt.show()
```

```python
#########################
# SIMULATION PARAMETERS
#########################
start_pos = np.array([[2, 6, .3]]).T # First State position
u = np.array([1.1, .01])             # Constant steering command (vel, steering angle radians)

std_range = 0.3     # Measurement range
std_bearing = 0.1   # Measurement bearing
landmarks = np.array([[5, 10], [10, 5]])  # Landmarks position

run_simulation(start_pos, u, std_range, std_bearing, landmarks)
```

- This simulations runs a filter prediction based on 2 landmarks we can see how the last part of the filter estimation gets worst uncertinaty (covariance maxtrix of the process). This is because the distance to a landamark is getting farther.

```python
#########################
# SIMULATION PARAMETERS
#########################
start_pos = np.array([[2, 6, .3]]).T # First State position
u = np.array([1.1, .01])             # Constant steering command (vel, steering angle radians)

std_range = 0.3     # Measurement range
std_bearing = 0.1   # Measurement bearing
landmarks = np.array([[5, 10], [10, 5], [15, 15]])  # Landmarks position

run_simulation(start_pos, u, std_range, std_bearing, landmarks)
```

- This second simulation runs a filter prediction based on 3 landmarks, we can se now how the uncertainity gets better results at the end of the filter estimation. Now the filer gets a landmark position close by and the update step of the filter gets better results.

```python

```