mixmax-py: a python implemented PRNG based on uniformly hyperbolic Anosov C-systems defined on a torus.
Copyright (C) 2019-2025 Michail Liarmakopoulos mlliarm@yandex.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
A python implementation of the MIXMAX PRNG.
In this project we successfully construct a python implementation of the two-parameter family of C-system operators A(N,s), as discussed in this [1] paper. A more general three-parameter family of C-system operators A(N,s,m) is calculated too. But our generator doesn't produce all the results of the three parameter family, whereas it works good for the two parameter family. Additionally, the module mixmax.py contains the class that generated pseudorandom numbers. The module main.py contains an example and stores 10E6 numbers to a TXT file for statistical testing.
There are two implementations. The first attempt was a naive approach, using vanilla python3 for the construction of the operator A(N,s). The second attempt, which is much better and faster is using cython for speeding up the construction process.
Run: python3 results_and_plots.py . You'll get instructions then.
An example of correct run: python3 results_and_plots.py 128 1 1.
Simply run in your terminal (see [2]):
python3 setup.py build_ext --inplace
The cythonized module will be inside the cython/scr/cython/ directory.
In order to see the results of a matrix of a specific dimension N you need to copy it in the directory cython where results_and_plots.py lies.
Run: python3 results_and_plots.py. You'll get instructions then.
A correct run: python3 results_and_plots.py 128 1 1.
Modify main.py as needed and run python3 main.py.
It's now set to create 64bit numbers binary file to run for Dieharder.
To create a file of about 800MB with 100M 64bit numbers run:
python3 main.pyTo run Dieharder:
dieharder -g 201 -f "Dieharder_64bit_N256_s-1_m1.bin -a
Meaning:
-g 201: read from file as binary-f: specify input file-a: run all tests
Both programs plot the distributions of the eigenvalues of the given A(N,s,m) for input variables N,s,m on the plane.
When m equals 1 then A(N,s,m) is the same matrix as the matrix A(N,s).
The results agree with the results presented in the paper [1]. The distribution of the eigenvalues in some cases follow the curve of a cardioid as expected. For various other values of N and s different shapes are being created. See inside the images directory for more examples.
The statistical testing of the pseudorandom numbers generated by these systems is still ongoing research.
See detailed results:
- Dieharder results
- TestU01 results: TBD
- NIST test results: TBD
- cython>=0.29.26
- numpy>=1.19.5
- matplotlib>=3.3.4
To my friend rembesques.
- [1] Konstantin Savvidy, George Savvidy, Spectrum and entropy of C-systems MIXMAX random number generator, (DOI), (arxiv).
- [2] Cython documentation
- [3] How to run TestU01 to test a random number generator (StackOverflow)
- [4] How to Test with TestU01
- [5] TestU01 docs
- [6] Dieharder test suite