Py4ti2 0.5.1
An interface to some 4ti2 functions
Requires Python: >=3.9

# Py4ti2 - An interface to 4ti2

## What is Py4ti2

Py4ti2 provides a Python interface to some of the computations performed by 4ti2 (https://4ti2.github.io/).

By now, it is possible to use:

* minimize, 
* groebner,
* normalform,
* markov,
* zbasis,
* walk, 
* hilbert,
* graver,
* zsolve,
* circuits,
* rays,
* qsolve

This software is inspired in PyNormaliz (https://github.com/Normaliz/PyNormaliz) and reuses some of its data transformation code.

## Requirements and installation 

First, 4ti2 is required with the groebner and zsolve components enabled. As well, GLPK (https://www.gnu.org/software/glpk/) is needed by 4ti2. GMP (https://gmplib.org/) is recommended. 4ti2 library folder should be specified to build Py4ti2, GLPK and GMP are expected to be installed in a default path, otherwise, use CPPFLAGS and LDFLAGS to specify compiler and linker information on those libraries.

For GNU/Linux or OSX users, open a ``terminal window'', select Py4ti2 as working directory to introduce the  command to build the Py4ti2 modules.

```shell
your_prompt$ cd WHERE_Py4ti2_IS_LOCATED
```

The variable FTI2_DIR is used to provide the path where 4ti2 libraries are installed.

Then execute the following to build:

```shell
prompt...Py4ti2$ FTI2_DIR=ROOT_OF_4ti2_INSTALLATION_HIERARCHY python3 -m build .
```

On success, use this to install the package:

```shell
prompt...Py4ti2$ pip install dist/dist/py4ti2-0.5.tar.gz
```



## Documentation

There is a module **Py4ti2int64** for 64 bit precision architecture, **Py4ti2int32** for 32 bits, and **Py4ti2gmp** for arbitrary precision computations.

It is recommended to read the manual page of the corresponding 4ti2 command to know which parameters are valid. Here, we show how to execute some examples that can be found in the 4ti2 source tree folder _test_.

***Important***: note that command line options cannot be specified at this moment. Py4ti2 interface allows the specification of matrix/vector input data.

We present some cases of use using 4ti2's distribution test data. 

### Minimal solution of an integer linear program

```python
from Py4ti2int32 import *

g=groebner(mat=[[3,5,7]])
print(minimize(lat=g, cost=[[1,1,1]], zsol=[3,6,9], sign=[1,1,1]))

[2, 1, 13]
```


### Gröbner bases

```python
# cuww1.1
from Py4ti2int32 import *
r=groebner("mat", [[12223, 12224, 36674, 61119, 85569]],\
           "mar", [[12224, -12223, 0, 0, 0], [2, -5, 1, 0, 0],\
                   [1, -9, 1, 1, 0], [1, -8, 0, 0, 1]], "sign", [1, 0, 1, 1, 1])

print([e for e in r])
[[-4075, -8155, 4074, 0, 1], [-4074, -8152, 4075, 0, 0], [-1, -4, 0, 1, 0], [0, -11, -1, 0, 2], [1, -8, 0, 0, 1], [1, 3, 1, 0, -1], [4076, 8147, -4074, 0, 0]]
```

```python
# cuww2.trunc1
from Py4ti2int64 import *
mar=[[-7339, 2444, 0, 2, 0, 0], [-7334, 2446, -1, 0, 0, 0], [-7333, 2445, 0, 1, -1, 0],\
     [-7, 0, -1, 0, 2, 0], [-7, 0, 0, -1, 1, 1], [-6, -1, 0, 1, 1, 0], [-6, -1, 1, 0, 0, 1],\
     [-5, -2, 1, 2, 0, 0], [-5, 0, -1, -1, 0, 2], [-4, -1, -1, 1, 0, 1], [-3, -2, -1, 3, 0, 0],\
     [-2, 0, 1, 0, 1, -1], [-2, 0, 2, -1, 0, 0], [-1, 1, -1, -1, 1, 0], [-1, 1, 0, -2, 0, 1]]

r=groebner("mat",[[12228, 36679, 36682, 48908, 61139, 73365]], "cost", [[1, 0, 0, 0, 0, 0]],\
          "lat", [[8, 4, 0, -5, 0, 0], [3, 2, 1, -3, 0, 0], [12221, 12224, 0, -12223, 0, 0],\
                  [2, 3, 0, -4, 1, 0], [-1, 1, 0, -2, 0, 1]], "mar", mar,\
           "weights", [[12228, 36679, 36682, 48908, 61139, 73365]], "weightsmax", [[1000000]])

print([e for e in r])
[[0, -3, -2, 5, -1, 0], [0, -2, 2, 3, 0, -2], [0, -2, 3, 2, -1, -1], [0, -2, 4, 1, -2, 0], [0, -2, 5, 0, -3, 1], [0, -1, -5, 3, 0, 1], [0, -1, -4, 2, -1, 2], [0, -1, -3, 1, -2, 3], [0, -1, -2, 0, -3, 4], [0, -1, 7, 0, 0, -3], [0, 0, -1, 1, 1, -1], [1, -1, 0, 2, 0, -1], [1, -1, 1, 1, -1, 0], [1, -1, 2, 0, -2, 1], [1, 0, 4, 0, 1, -3], [1, 0, 5, -1, 0, -2], [1, 1, -3, 0, 1, 0], [1, 1, -2, -1, 0, 1], [1, 2, 3, -4, 0, 0], [2, 0, -2, 1, 0, 0], [2, 0, -1, 0, -1, 1], [2, 1, 3, -2, 0, -1], [3, 0, 3, 0, 0, -2], [3, 2, 1, -3, 0, 0], [4, 1, 1, -1, 0, -1], [5, 0, 2, 0, -1, -1], [5, 2, -1, -2, 0, 0], [6, 1, -1, 0, 0, -1], [7, 0, 1, 0, -2, 0]]
```

### Normal form

```python
# 4coins
from Py4ti2gmp import *

nf=normalform("mat", [[1, 1, 1, 1], [1, 5, 10, 25]], 
              "cost", [[0, 1, 0, 1]],
              "gro", [[-5, 3, 4, -2], [-5, 6, 0, -1],[0, 3, -4, 1], [5, 0, -8, 3]],
              "feas", [[4, 1232534646456456456389274293472974242374234729743, 0, 3]])
print([e for e in nf])

[[684741470253586920216263496373874579096797072079, 2, 547793176202869536173010797099099663277437657668, 1]]
```

### Markov basis

```python
# grin10900.1

lat = [[-3, 2, -2, 0, 0, 0, -1, 1, 0, 1, 1, 3, 0], [1, 1, 2, 0, 1, -1, -1, 1, -2, 0, -2, -3, 1], [-3, 1, -4, 1, 0, -1, 2, 2, 2, 0, 2, 1, -1], [21, -21, 8, -2, -4, 5, 14, -15, 9, -8, -1, -10, -3], [42, -43, 15, -2, -7, 10, 25, -25, 17, -18, 1, -24, -6], [-1, 0, 4, -1, 3, -2, 1, -1, 0, -1, 0, -2, 1], [-83, 63, -41, 6, 9, -8, -44, 45, -17, 28, 17, 59, 5], [1, -1, -1, 2, 3, -1, -1, -2, 3, -2, 1, -1, 0], [-5, 3, -1, 1, -4, 3, 1, 1, 2, 0, 1, 2, -1]]
zsol = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

from Py4ti2int64 import *

mar = markov("lat", lat, "zsol", zsol)
print([e for e in mar])

[[0, 0, 0, 2, 1, -3, -5, 0, -2, 3, 2, 4, -3], [0, 0, 0, 2, 2, -1, 0, -4, 2, 2, -7, 1, 0], .... [7, -4, -1, 1, 0, 0, -5, 0, -3, 1, 0, 0, -1], [8, -6, -3, 0, 0, 0, 0, -2, 0, 0, 0, 0, -1]]
```

```python
# prob16

mat = [[35113, 36869, 46647, 53560, 81518, 85287, 102780, 115459, 146791, 147097]]
lat = [[-1, 1, 2, -1, 1, 2, 0, 0, -2, 0], [0, 1, -2, -2, -1, 1, -1, 1, 0, 1], [0, 0, -1, 1, -2, 1, 1, 1, 1, -2], [-2, 1, -1, -1, 0, -1, 1, 1, -2, 2], [-1, -1, -2, 2, 0, 1, -2, -1, 1, 1], [3, 1, -2, 1, 0, 0, -1, 0, -1, 1], [-2, 2, 2, 0, 0, 0, 1, -3, 1, 0], [-3, 0, 0, 1, 2, -1, 2, -2, 2, -2], [1, 5, 0, 2, 0, -3, -6, 6, -1, 0]]

from Py4ti2int64 import *

mar = markov("lat", lat, "mat", mat)
print([e for e in mar])

[[0, 0, 1, 0, 0, -5, 4, 1, -1, 0], [0, 0, 1, 4, -3, 2, -1, -2, 1, 0], [0, 0, 4, -5, 1, 0, 0, 0, 1, -1], .... [25, -7, -1, -4, 1, 0, 0, 0, -3, 0], [26, -8, -3, -3, 0, -2, 0, 0, -1, 0]]
```

### Integer lattice basis

```python
# cuww4

mat = [[13211, 13212, 39638, 52844, 66060, 79268, 92482]]

from Py4ti2int64 import *

lat = zbasis("mat", mat)
print([e for e in lat])
```

### Integer linear program minimal solution

Notes:
* _cost_ input is needed according to 4ti2 source code.
* _zsol_ input is optional according to the examples and 4ti2 source code.

```python
# cuww1

mat = [[12223, 12224, 36674, 61119, 85569]]
cost = [[1, 1, 0, 0, 0]]
cost_start = [[-1, 0, 0, 0, 0]]
gro_start = [[-7336, 3, 2444, 0, 0], [-7334, -2, 2445, 0, 0], [-2, 5, -1, 0, 0], [-1, -4, 0, 1, 0], [-1, -3, -1, 0, 1]]

from Py4ti2int64 import *

gro = walk("mat", mat, "cost", cost, "cost.start", cost_start, "gro.start", gro_start)
print([e for e in gro])

[[-2, 2, 2, 3, -3], [-2, 3, 1, 2, -2], [-2, 4, 0, 1, -1], .... [7334, 2, -2445, 0, 0], [7336, -3, -2444, 0, 0]]
```

### Hilbert bases

```python
# 44.mat

from Py4ti2int64 import *
mat=[[1, 1, 1, 1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0], 
     [1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0],
     [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1],
     [0, 1, 1, 1, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0],
     [1, 0, 1, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0],
     [1, 1, 0, 1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0],
     [1, 1, 1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1],
     [0, 1, 1, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1],
     [1, 1, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0]]
r=hilbert("mat", mat)

print([e for e in r])
['zhom', [[0, 1, 0, 1, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0, 2, 0, 1, 1, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 1, 0, 1], [1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2, 1, 0, 1, 0], [0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0], [1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 2, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], [0, 0, 2, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0], [0, 2, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1], [0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0], [1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1], [1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 2, 0]], 'zfree', []]
```

```python
# a1.mat

from Py4ti2int64 import *
mat=[[ 0,  0, -1,  1,  0,  0,  0,  0, -2,  0,  0,  1,  0,  1,  2,  0,  0,  1,  0, -1, -1, -1,  0, -1],
[ 0,  0,  1, -1,  0,  0, -2, -2,  0,  2,  2,  1,  2,  1,  0,  2,  2,  1, -2, -1, -1, -1, -2, -1],
[ 0,  0, -1, -1,  0, -2,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1,  0,  1,  1,  1,  0,  1],
[ 0,  0,  1, -1, -2,  0,  0,  0,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0,  1, -1,  1,  0,  1],
[ 0, -2, -1,  1,  0,  0,  0, -2,  0,  0,  2,  1,  0,  1,  0,  0,  2,  1,  0, -1,  1, -1,  0, -1],
[-2,  0, -1, -1,  0,  0,  0,  2,  0,  0, -2, -1,  0, -1,  0,  0, -2, -1,  2,  1,  1,  1,  2,  1],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1,  0,  0,  0,  0,  1,  1],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0, -1,  0],
[ 0,  0,  1, -1,  0,  0,  0,  0,  0,  0,  0, -1,  0, -1, -2,  0,  0, -1,  0,  1,  1,  1,  0,  1],
[ 0,  0, -1,  1,  0,  0,  0,  0,  0,  0,  0,  1, -2, -1,  0,  0,  0,  1,  0, -1,  1,  1,  0, -1],
[ 0,  0, -1,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1,  0, -1,  1, -1,  0, -1],
[ 0,  0,  1, -1,  0,  0,  0,  0,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0,  1, -1, -1,  0,  1],
[ 0,  0, -1,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0, -1, -1, -1,  0, -1],
[ 0,  0,  1, -1,  0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  0,  0,  0, -1,  0,  1, -1,  1,  0,  1],
[ 0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
[ 0,  0,  0,  0,  0,  0,  0,  1,  0, -1, -1, -1,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0],
[ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0, -1, -1, -1,  0, -1],
[ 0,  0, -1, -1,  0,  0,  0,  0,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1,  0, -1,  1,  1,  0,  1],
[ 0,  0, -1, -1,  0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  0,  0,  0,  1,  0,  1,  1,  1,  0,  1],
[ 0,  0,  0,  0,  0,  0,  0,  1,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
[ 0,  0,  1,  1,  0,  0,  0, -2,  0,  0,  2,  1,  0,  1,  0,  0,  0, -1, -2, -1, -1, -1,  0, -1]]
rel=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
sign=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
r=hilbert("mat", mat, "rel", rel, "sign", sign)

print([e for e in r])
['zhom', [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0]], 'zfree', []]
```

### Graver bases

```python
# small

from Py4ti2int64 import *

r=graver("mat", [[1, 1, 1, 1, 1], [1, 2, 3, 4, 5]], "sign", [-1, 2, 1, 1, 0])

print([e for e in r])
[[0, -1, 0, 3, -2], [0, -2, 3, 0, -1], [-1, 0, 2, 0, -1], [-3, 4, 0, 0, -1], [-2, 2, 1, 0, -1], [-1, 1, 0, 1, -1], [0, -1, 1, 1, -1], [-1, 0, 1, 2, -2], [-1, 0, 0, 4, -3]]
```
### Zsolve

```python
# affine

from Py4ti2int64 import *

r=zsolve("lat",[[1, -1, 1, 0], [2, -3, 0, 1]],"sign",[1, 2, 2, 0])

print([e for e in r])
['zinhom', [[0, 0, 0, 0]], 'zhom', [[1, 0, 3, -1], [0, -1, -2, 1], [0, 1, 2, -1], [1, -1, 1, 0], [1, -2, -1, 1], [2, -3, 0, 1]], 'zfree', []]
```

```python
# hppi6

from Py4ti2int32 import *

zsolve("mat",[[1, 1, 1, 1, 1, 1], [1, 2, 3, 4, 5, 6]],"sign",[1, 1, 1, 2, 2, 2], "rel", [-1, -1], 
      "lb", [0, 0, 0, 1, -1, -1], "ub", [1, 4, -1, -1, 2, 1])

print([e for e in r])
['zinhom', [[0, 0, 0, 0]], 'zhom', [[1, 0, 3, -1], [0, -1, -2, 1], [0, 1, 2, -1], [1, -1, 1, 0], [1, -2, -1, 1], [2, -3, 0, 1]], 'zfree', []]
```

```python
# m33

from Py4ti2gmp import *

problem=["mat",[[0, 0, 0, 0, 0, 3, -4, -1, 2], [0, 0, 0, 0, 1, -1, 1, 0, -1], [0, 0, 0, 1, 2, 0, 0, -1, -2], 
                 [0, 0, 1, 0, 1, 0, 0, -1, -1], [0, 1, 2, 0, 0, 0, 0, -1, -2], [1, 0, 2, 0, 0, 0, 0, -2, -1], 
                 [-2, 0, -2, 0, 0, 0, 0, 3, 0], [-2, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, -2, 0, 0, 0, 0, 1, 0], 
                 [0, 0, 0, 0, 0, 0, 0, -1, 0]], 
          "rel", [0, 0, 0, 0, 0, 0, -1, -1, -1, -1], 
          "sign", [0, 0, 0, 0, 0, 0, 0, 0, 0]]

r=zsolve(*problem)

print([e for e in r])
['zinhom', [[0, 0, 0, 0, 0, 0, 0, 0, 0]], 'zhom', [[1, 0, 2, 2, 1, 0, 0, 2, 1], [2, 0, 1, 0, 1, 2, 1, 2, 0], [1, 2, 0, 0, 1, 2, 2, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 2, 1, 2, 1, 0, 1, 0, 2]], 'zfree', []]
```

### Circuits

```python
from Py4ti2int64 import *

# 33.1

data=[[1, 1, 1, -1, -1, -1, 0, 0, 0], 
      [1, 1, 1, 0, 0, 0, -1, -1, -1], 
      [0, 1, 1, -1, 0, 0, -1, 0, 0], 
      [1, 0, 1, 0, -1, 0, 0, -1, 0], 
      [1, 1, 0, 0, 0, -1, 0, 0, -1], 
      [0, 1, 1, 0, -1, 0, 0, 0, -1], 
      [1, 1, 0, 0, -1, 0, -1, 0, 0]]

#r=circuits("mat", data, "sign", [1, 2, 2, 2, 2, 2, 2, 2, 2])

r=circuits(mat=data, sign=[1, 2, 2, 2, 2, 2, 2, 2, 2])

print([e for e in r])
['cir', [[1, -4, 0, -2, -1, 0, -2, 2, -3], [1, -2, -2, -4, -1, 2, 0, 0, -3], [1, -2, 1, 0, 0, 0, -1, 2, -1], [1, -1, 0, -1, 0, 1, 0, 1, -1], [1, 0, -1, -2, 0, 2, 1, 0, -1], [1, 0, 2, 2, 1, 0, 0, 2, 1], [1, 2, 0, 0, 1, 2, 2, 0, 1], [2, -2, 3, 2, 1, 0, -1, 4, 0], [2, -1, 2, 1, 1, 1, 0, 3, 0], [2, 0, 1, 0, 1, 2, 1, 2, 0], [2, 1, 0, -1, 1, 3, 2, 1, 0], [2, 2, -1, -2, 1, 4, 3, 0, 0], [3, -2, 2, 0, 1, 2, 0, 4, -1], [3, 0, 0, -2, 1, 4, 2, 2, -1], [0, 0, 3, 4, 1, -2, -1, 2, 2], [0, 1, -1, -1, 0, 1, 1, -1, 0], [0, 1, 2, 3, 1, -1, 0, 1, 2], [0, 2, 1, 2, 1, 0, 1, 0, 2], [0, 3, 0, 1, 1, 1, 2, -1, 2], [0, 4, -1, 0, 1, 2, 3, -2, 2]], 'qfree', []]
```

### Rays

```python
from Py4ti2gmp import *

# 55.r

data=[[1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1],
[0, 1, 1, 1, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
[1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0],
[1, 1, 0, 1, 1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0],
[1, 1, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0],
[1, 1, 1, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1],
[0, 1, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[1, 1, 1, 1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0]]

r=rays(mat=data)

print([e for e in r])
['ray', [[0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], ..., [6, 0, 0, 0, 3, 0, 1, 0, 2, 6, 0, 8, 1, 0, 0, 0, 0, 8, 1, 0, 3, 0, 0, 6, 0], [6, 0, 0, 0, 3, 0, 1, 8, 0, 0, 0, 0, 1, 8, 0, 0, 2, 0, 1, 6, 3, 6, 0, 0, 0]], 'qfree', []]
```

### QSolve

```python
from Py4ti2int32 import *

# 33.c

data=[[1, 1, 1, -1, -1, -1, 0, 0, 0], 
 [1, 1, 1, 0, 0, 0, -1, -1, -1], 
 [0, 1, 1, -1, 0, 0, -1, 0, 0], 
 [1, 0, 1, 0, -1, 0, 0, -1, 0], 
 [1, 1, 0, 0, 0, -1, 0, 0, -1], 
 [0, 1, 1, 0, -1, 0, 0, 0, -1], 
 [1, 1, 0, 0, -1, 0, -1, 0, 0]]

print(qsolve(mat=data, sign=[2, 2, 2, 2, 2, 2, 2, 2, 2]))
('qhom', [[0, 0, 3, 4, 1, -2, -1, 2, 2], [0, 1, -1, -1, 0, 1, 1, -1, 0], [0, 1, 2, 3, 1, -1, 0, 1, 2], [0, 2, 1, 2, 1, 0, 1, 0, 2], [0, 3, 0, 1, 1, 1, 2, -1, 2], [0, 4, -1, 0, 1, 2, 3, -2, 2], [1, -4, 0, -2, -1, 0, -2, 2, -3], [1, -2, -2, -4, -1, 2, 0, 0, -3], [1, -2, 1, 0, 0, 0, -1, 2, -1], [1, -1, 0, -1, 0, 1, 0, 1, -1], [1, 0, -1, -2, 0, 2, 1, 0, -1], [1, 0, 2, 2, 1, 0, 0, 2, 1], [1, 2, 0, 0, 1, 2, 2, 0, 1], [2, -2, 3, 2, 1, 0, -1, 4, 0], [2, -1, 2, 1, 1, 1, 0, 3, 0], [2, 0, 1, 0, 1, 2, 1, 2, 0], [2, 1, 0, -1, 1, 3, 2, 1, 0], [2, 2, -1, -2, 1, 4, 3, 0, 0], [3, -2, 2, 0, 1, 2, 0, 4, -1], [3, 0, 0, -2, 1, 4, 2, 2, -1], [0, 0, -3, -4, -1, 2, 1, -2, -2], [0, -1, 1, 1, 0, -1, -1, 1, 0], [0, -1, -2, -3, -1, 1, 0, -1, -2], [0, -2, -1, -2, -1, 0, -1, 0, -2], [0, -3, 0, -1, -1, -1, -2, 1, -2], [0, -4, 1, 0, -1, -2, -3, 2, -2], [-1, 4, 0, 2, 1, 0, 2, -2, 3], [-1, 2, 2, 4, 1, -2, 0, 0, 3], [-1, 2, -1, 0, 0, 0, 1, -2, 1], [-1, 1, 0, 1, 0, -1, 0, -1, 1], [-1, 0, 1, 2, 0, -2, -1, 0, 1], [-1, 0, -2, -2, -1, 0, 0, -2, -1], [-1, -2, 0, 0, -1, -2, -2, 0, -1], [-2, 2, -3, -2, -1, 0, 1, -4, 0], [-2, 1, -2, -1, -1, -1, 0, -3, 0], [-2, 0, -1, 0, -1, -2, -1, -2, 0], [-2, -1, 0, 1, -1, -3, -2, -1, 0], [-2, -2, 1, 2, -1, -4, -3, 0, 0], [-3, 2, -2, 0, -1, -2, 0, -4, 1], [-3, 0, 0, 2, -1, -4, -2, -2, 1]], 'qfree', [])
```