c++ - Biblioteca exacta de álgebra lineal de campo finito grande(por ejemplo, GF(2 ^ 128)/GF(2 ^ 256))
math linear-algebra (1)
General
Estoy buscando una biblioteca que sea capaz de hacer cálculos exactos en campos finitos grandes como GF (2 128 ) / 𝔽 2 128 y GF (2 256 ) / 𝔽 2 256 . Enumeré las características que necesito y las características que serían geniales a continuación. Obviamente, la biblioteca debería ser lo más rápida posible :-). Ah, ya que no soy un maestro de C ++ (y probablemente la mayoría de las bibliotecas son C ++), el código de ejemplo de, por ejemplo, genera un elemento aleatorio / una constante y lo multiplica a su inverso multiplicativo
Características imprescindibles
- Adición de elementos de campo
- Multiplicación de elemento de campo.
- Encuentra el inverso multiplicativo de un elemento de campo
Es bueno tener características
- Soporte de matrices / vectores
- Soporte de elementos aleatorios
Bibliotecas que ya he visto que probablemente no funcionen
- FFLAS/FFPACK , parece no funcionar con campos finitos tan grandes
- Givaro , parece no trabajar en campos finitos tan grandes
Bibliotecas que ya vi que podrían funcionar (pero no pude usar)
-
NTL , no pude invertir un elemento, pero realmente debería funcionar ya que SAGE parece usar esta biblioteca cuando define GF (2 ^ 256) y allí se puede invertir un elemento utilizandox^(-1)
- PARI/GP , no pude encontrar todo lo que necesito en la documentación, pero la documentación de SAGE dice que debería funcionar
Otras notas
- Estoy escribiendo un programa de Haskell e interactuaré con esa biblioteca más adelante, así que una interfaz de Haskell más fácil es mejor :-)
La biblioteca NTL parece funcionar, usando este código (lo siento, no puedo programar en C ++)
#include <NTL/GF2E.h>
#include <NTL/GF2EX.h>
#include <NTL/GF2X.h>
#include <NTL/GF2XFactoring.h>
NTL_CLIENT
int main()
{
GF2X P = BuildIrred_GF2X(256);
GF2E::init(P);
GF2E zero = GF2E::zero();
GF2E one;
GF2E r = random_GF2E();
GF2E r2 = random_GF2E();
conv(one, 1L);
cout << "Cardinality: " << GF2E::cardinality() << endl;
cout << "ZERO: " << zero << " --> " << IsZero(zero) << endl;
cout << "ONE: " << one << " --> " << IsOne(one) << endl;
cout << "1/r: " << 1/r << ", r * (1/r): " << (r * (1/r)) << endl;
cout << "1/r2: " << 1/r2 << ", r2 * (1/r2): " << (r2 * (1/r2)) << endl;
}
Parece funcionar, prueba (salida de este programa):
Cardinality: 115792089237316195423570985008687907853269984665640564039457584007913129639936
ZERO: [] --> 1
ONE: [1] --> 1
1/r: [0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 1 1 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1], r * (1/r): [1]
1/r2: [1 0 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 0 1 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 1], r2 * (1/r2): [1]
Incluso la inversión parece funcionar (desplácese tan correctamente como sea posible en el ejemplo de salida anterior) :-)