Algoritmo de Schönhage - Estrassen


El algoritmo de Schönhage–Strassen es un algoritmo de multiplicación asintoticamente rápida para grandes enteros, publicado por Arnold Schönhage y Volker Strassen en 1971. Funciona aplicando recursivamente la transformación rápida Fourier (FFT) sobre los enteros modulo 2n+1. La complejidad del tiempo de ejecución para multiplicar dos n- números de dígitos usando el algoritmo es en la gran notación O.
El algoritmo Schönhage-Strassen fue el método de multiplicación asintotically más rápido conocido desde 1971 hasta 2007. Es asintomáticamente más rápido que los métodos más antiguos como la multiplicación Karatsuba y Toom-Cook, y comienza a superarlos en la práctica para números más allá de 10.000 a 100.000 dígitos decimales. En 2007, Martin Fürer publicó un algoritmo con mayor complejidad asintotica. En 2019, David Harvey y Joris van der Hoeven demostraron que la multiplicación de varios dígitos tiene teoría complejidad; sin embargo, su algoritmo tiene factores constantes que lo hacen imposiblemente lento para cualquier problema práctico concebible (ver algoritmo galáctico).
Las aplicaciones del algoritmo Schönhage -Strassen incluyen grandes cálculos realizados por su propio bien, como la gran búsqueda de Internet Mersenne Prime y las aproximaciones de π, así como aplicaciones prácticas como la factorización de la curva elíptica de Lenstra a través de la sustitución de Kronecker, que reduce a la multiplicación entera.
Descripción
Esta sección tiene una versión simplificada del algoritmo, mostrando cómo calcular el producto de dos números naturales , modulo un número de la forma , donde es un número fijo. Los enteros se dividirán en bloques de bits, así que en implementaciones prácticas, es importante lograr el equilibrio adecuado entre los parámetros . En cualquier caso, este algoritmo proporcionará una manera de multiplicar dos enteros positivos, proporcionados es elegido para que .
Vamos. ser el número de bits en las señales y , donde es un poder de dos. Divide las señales y en bloques de pica cada uno, almacenando los bloques resultantes como arrays (cuyas entradas consideraremos para la simplicidad como enteros de precisión arbitrarios).
Ahora seleccionamos un módulo para la transformación Fourier, como sigue. Vamos. ser tal . También se puso , y considerar los elementos de los arrays como (precisión arbitraria) modulo de enteros . Observa que desde entonces , el módulo es lo suficientemente grande para acomodar cualquier carga que puede resultar de multiplicación y . Así, el producto (modulo) ) se puede calcular evaluando la convolución de . También, con , tenemos , y así es un primitivo la raíz del modulo de unidad .
Ahora tomamos la discreta transformación Fourier de los arrays en el anillo , utilizando la raíz de la unidad para la base Fourier, dando los arrays transformados . Porque... es un poder de dos, esto se puede lograr en el tiempo logarítmico usando una rápida transformación Fourier.
Vamos. (producto puntero), y computar la transformación inversa de la matriz , nuevamente utilizando la raíz de la unidad . El array es ahora la convolución de los arrays . Finalmente, el producto se da por evaluación
Este algoritmo básico se puede mejorar de varias maneras. En primer lugar, no es necesario almacenar los dígitos de a la precisión arbitraria, pero sólo hasta bits, que da una representación de máquina más eficiente de los arrays . En segundo lugar, está claro que las multiplicaciones en las transformaciones de avance son simples cambios de bits. Con cierto cuidado, también es posible calcular la transformación inversa utilizando sólo turnos. Cuidar, por lo tanto es posible eliminar cualquier verdadera multiplicación del algoritmo excepto para donde el producto puntero se evalúa. Por lo tanto, es ventajoso seleccionar los parámetros para que este producto puntero pueda ser realizado eficientemente, ya sea porque es una sola palabra de máquina o usando algún algoritmo optimizado para multiplicar enteros de un número de palabras (idealmente pequeño). Seleccionar los parámetros es por lo tanto un área importante para mayor optimización del método.
Detalles
Todo número en base B, se puede escribir como un polinomio:
Además, la multiplicación de dos números podría considerarse como un producto de dos polinomios:
Porque, por : , Tenemos una convolución.
Mediante el uso de FFT (fast Fourier transform), utilizado en versión original en lugar de NTT, con la regla de la convolución; obtenemos
Eso es; , donde es el coeficiente correspondiente en el espacio cuatro. Esto también se puede escribir como: fft(a * b) = fft(a) ● fft(b).
Tenemos los mismos coeficientes debido a la linealidad bajo la transformada de Fourier y porque estos polinomios sólo constan de un término único por coeficiente:
- y
Regla de la revolución:
Hemos reducido nuestro problema de convolución al problema del producto, a través de FFT.
Al encontrar ifft (interpolación polinomial), para cada , uno consigue los coeficientes deseados.
El algoritmo utiliza la estrategia de dividir y conquistar para dividir el problema en subproblemas.
Convolución bajo mod N
- , donde y en el algoritmo de Schönhage-Strassen.
Al permitir:
- y
Donde es la raíz n-th
Se ve que:
Esto significa que uno puede usar peso , y luego se multiplica con después.
En lugar de usar peso; uno puede debido a , en el primer paso de la recursión (cuando ), calcular:
En FFT normal, que opera con números complejos, se usaría:
Sin embargo, FFT también se puede utilizar como un NTT (general transformación teorética) en Schönhage–Strassen. Esto significa que tenemos que usar Silencio que generan números en un campo finito (por ejemplo ).
Una raíz de la unidad bajo un campo finito GF(r), es un elemento tal que o . Por ejemplo GF(p), donde p es un primo, da .
Note que dentro y dentro . Para estos candidatos, bajo su campo finito, y por lo tanto actuar la manera que queremos.
Sin embargo, aún se pueden usar los mismos algoritmos FFT, siempre que θ sea la raíz de la unidad de un campo finito.
Para encontrar la transformación FFT/NTT, hacemos lo siguiente:
Primer producto da contribución a , para cada k. Segunda contribución debido a mod .
Para hacer el inverso:
- o
dependiendo de si fft usa datos normalizados o no.
Uno se multiplica por , para normailizar datos fft a un rango específico, donde , donde m se encuentra utilizando inverso multiplicativo modular.
Detalles de implementación
Por qué N = 2M + 1 en mod N
En el algoritmo Schönhage–Strassen, . Uno debe pensar en esto como un árbol binario, donde uno tiene valores en . Dejando , una lata para cada K encontrar todos : Uno puede agrupar todos pares en grupos M diferentes. Uso grupo pares a través de la convolución, es un problema clásico en algoritmos. Por ejemplo: Let k be total income and i ser hombres ingresos y j ingresos de las mujeres; mediante el uso de la convolución, se puede agrupar en K grupos basados en el ingreso total deseado.
Teniendo esto en cuenta, Ayúdanos a grupos en grupos, para cada grupo de subtascos en profundidad k; en el árbol con
Note que Para algunos L. Este es el número de Fermat. Al hacer mod Tenemos algo llamado anillo de Fermat.
Debido a que algunos números de Fermat son primos de Fermat, en algunos casos se pueden evitar los cálculos.
Hay otros N que podría haber sido utilizado, por supuesto, con las mismas ventajas de número primo. Dejando , uno tiene el número máximo en un número binario con bits. es un número de Mersenne, que en algunos casos es un Mersenne primo. Es un candidato natural contra el número de Fermat
En busca de otro N
Hacer varios cálculos mod contra diferentes N puede ser útil cuando se trata de resolver productos enteros. Utilizando el teorema del resto chino, después de dividir M en tipos diferentes más pequeños de N, se puede encontrar la respuesta de la multiplicación xy
Los números de Fermat y los números de Mersenne son solo dos tipos de números, en algo llamado número de Fermat Mersenne generalizado (GSM); con fórmula:
En esta fórmula; es un número de Fermat, y es un número Mersenne.
Esta fórmula se puede utilizar para generar conjuntos de ecuaciones, que se pueden utilizar en CRT (teorema del resto chino):
- , donde g es un número tal que existe x Donde , suponiendo
Además; , donde a es un elemento que genera elementos en de manera cíclica.
Si , donde Entonces .
Cómo elegir K para un N específico
La siguiente fórmula ayuda a encontrar un K adecuado (número de grupos para dividir N bits en) dado el tamaño de bits N calculando la eficiencia:
N es tamaño de bits (el que se utiliza en ) en el nivel más exterior. K da grupos de bits, donde .
n se encuentra a través N, K y k encontrando lo más pequeño x, tal que
Si uno asume eficiencia por encima del 50%, y k es muy pequeño en comparación con el resto de la fórmula;
Esto significa: Cuando algo es muy efectivo; K está obligado por encima o asintotípicamente ligados arriba por
Pseudocódigo
A continuación del algoritmo, el algoritmo de multiplicación modular estándar de Schönhage-Strassen (con algunas optimizaciones) se encuentra en una descripción general a través de
- Dividir ambos números de entrada a y b en n coeficientes de s bits cada uno.
Usar al menos pedazos para almacenarlos,
para permitir la codificación del valor - Peso ambos coeficientes vectores según (2.24) con poderes de Silencio realizando ciclismo Los cambia.
- Saque los coeficientes y .
- Evaluate y . Multiplicaciones por poderes de ω son cambios cíclicos.
- Do n multiplicaciones puntuales dentro . Si SMUL se utiliza recursivamente, proporcionar K como parámetro. De lo contrario, utilice alguna otra función de multiplicación como T3MUL y reducir el modulo Después.
- Saque los coeficientes de producto .
- Evaluar los coeficientes de producto .
- Aplicar los contrapesos a los según (2.25). Desde sigue que
- Normalizar el con (de nuevo un cambio cíclico).
- Añadir a la y propagar las cargas. Asegúrese de manejar adecuadamente los coeficientes negativos.
- Hacer un modulo de reducción .
- T3MUL = Toom–Cook multiplication
- SMUL = multiplicación de Schönhage–Strassen
- Evaluación = FFT/IFFT
Estudio adicional
Para obtener detalles sobre la implementación, se puede leer el libro Números primos: una perspectiva computacional. Esta variante difiere algo del método original de Schönhage en que explota la transformada ponderada discreta para realizar convoluciones negacíclicas de manera más eficiente. Otra fuente de información detallada es El arte de la programación informática de Knuth.
Optimizaciones
Esta sección explica una serie de optimizaciones prácticas importantes al implementar Schönhage–Strassen.
Uso de otro algoritmo de multiplicaciones, algoritmo interno
Por debajo de un determinado punto de corte, es más eficiente utilizar otros algoritmos de multiplicación, como la multiplicación de Toom-Cook.
Raíz cuadrada de 2 truco
La idea es usar como raíz de la unidad del orden en campo finito (es una solución a la ecuación ), cuando los valores de ponderación en NTT (número de transformación teorética) enfoque. Se ha demostrado que ahorra un 10% en tiempo de multiplicación entero.
El truco de Granlund
Dejando ; uno puede calcular y . En combinación con CRT (Teorema de Restante chino), a encontrar valores exactos de la multiplicación uv