8 votos

Multiplicación Karatsuba con enteros de tamaño 3

Entiendo cómo aplicar la multiplicación de Karatsuba en números enteros de 2 dígitos.

$$\begin{array} \quad & \quad & x & y \\ \times & \quad & z & w \\ \hline \quad &?&?&? \end{array}$$

$$\begin{align} i & = zx \\ ii & = wy \\ iii & = (x+y)(w+z) \end{align}$$

y el resultado es $$i \cdot 10^2n + [(iii - ii - i) \cdot 10^n] + ii$$

Entonces mi pregunta es, ¿cómo aplico esto en números enteros de 3 dígitos?

es decir, este es el problema:

Tengo 2 números de tres cifras y quiero dividirlo en 5 multiplicaciones y son de tamaño $n/3$ . Estoy bastante seguro de que tengo que usar la multiplicación Karatsuba, pero no estoy del todo seguro... Soy bastante nuevo aquí así que mi redacción puede ser muy pobre. Espero haberme expresado lo suficientemente bien. Gracias por cualquier ayuda.

11voto

Aquarius Power Puntos 814

Bueno, yo también soy bastante nuevo en la multiplicación y he tropezado con tu pregunta después de buscar el algoritmo de la multiplicación sobre la resolución de la multiplicación de dos números de 3 dígitos con sólo 5 multiplicaciones.

Así que...

  1. Lo primero - con Karatsuba probablemente no puedas hacer esto. Derivado de la versión de 2 dígitos del algoritmo: $$ (10a + b) (10x + y) = 100ax + by + 10\Big( (a+b)(x+y) - ax - by\Big) $$ y aplicándolo recursivamente obtendremos $$ \Big( \; 10 (10a + b) + c \; \Big) \cdot \Big( \; 10 (10x + y) + z \; \Big) = 100 (10a+b)(10x+y) \;+\; cz \;+\; 10\Big( (10a+b+c)(10x+y+z) \; - \; (10a+b)(10x+y) \; - \; cz \Big) = 100 \Bigg( 100ax + by + 10 \Big( (a+b)(x+y) - ax - by \Big) \Bigg) \;+\; cz \;+\; 10\Bigg\{ 100ax \;+\; (b+c)(y+z) \;+\; 10\bigg[ \; (a+b+c)(x+y+z) \;-\; ax \;-\; (b+c)(y+z) \; \bigg] \;-\; \bigg[ \; 100ax \;+\; by \;+\; 10\Big( (a+b)(x+y) - ax - by \Big) \bigg] \;-\; cz \Bigg\} \;\;\;\; = \;\;\;\;10^4ax +10^2by +10^3(a+b)(x+y)-10^3ax-10^3by+cz+10^3ax+10(b+c)(y+z)+10^2(a+b+c)(x+y+z)-10^2ax-10^2(b+c)(y+z)-10^3ax-10by-10^2(a+b)(x+y)+10^2ax+10^2by-10cz \;\;\;\; = \;\;\;\; 10^4ax +10^3\Big( (a+b)(x+y)-ax-by \Big) + 10^2\Big( (a+b+c)(x+y+z)-(b+c)(y+z)-(a+b)(x+y)+2by\Big)+10\Big((b+c)(y+z)-by-cz\Big)+cz $$ Así se reduce el número de multiplicaciones necesarias a 6:

    • hacha
    • por
    • cz
    • (a+b)(x+y)
    • (b+c)(y+z)
    • (a+b+c)(x+y+z)
  2. Pero debería ser posible hacerlo con Multiplicación Toom-Cook algoritmo.

¿Qué idea hay detrás de esto? Sencillamente, en lugar de hacer cálculos, tratamos cada conjunto de números como un polinomio: $$ p(t) = at^2 + bt + c $$ $$ q(t) = xt^2 + yt + z $$

Y buscamos el polinomio:

$$ w(t) = p(q) \cdot q(t) = w_4 t^4 + w_3 t^3 + w_2 t^2 + w_1 t + w_0 $$

Como se puede ver fácilmente cada coeficiente $w_i$ de nuestro $w(t)$ polinomio es uno de los productos de la multiplicación. Para evitar la multiplicación de polinomios (que mataría el caso) intentaremos calcular los coeficientes de $w(t)$ utilizando la interpolación en nuestro $p(t)$ y $q(t)$ polinomios. Para ello necesitamos algunos puntos de interpolación. Para 5 variables ( $w_0,w_1,w_2,w_3,w_4$ ) necesitamos 5 puntos. Que sean (como en el artículo de la wikipedia) $t \in \{-2,-1,0,1,\infty\} $ .

Los puntos de evaluación del polinomio pueden ser los que usted desee. Pero es común elegir $0$ y $\infty$ entre ellos. En el caso de los polinomios con valor en $\infty$ no tiene mucho sentido, así que en lugar de esto estamos usando $$ p(\infty) = \lim_{t \to \infty} {{p(t)} \over {t^{deg(p)}}} $$

Y por lo tanto siempre es coeficiente de mayor poder (como $w_4$ en caso de $w(t)$ )

Una vez explicado esto vamos a probarlo:

$$ \begin{array}[b]{l} t=0 &&p(0) = c \\ &&q(0) = z \\ t=1 &&p(1) = a +b +c \\ &&q(1) = x +y +z \\ t=-1 &&p(-1) = a -b +c \\ &&q(-1) = x -y +z \\ t=-2 &&p(-2) = 4a-2b +c \\ &&q(-2) = 4x-2y +z \\ t=\infty &&p(\infty) = a \\ &&q(\infty) = x \end{array} $$ Lo que nos lleva a: $$ \begin{array}[b]{l} w(0) &&= w_0 &&= cz \\ w(1) &&= w_4 +w_3+w_2+w_1+w_0 &&= (a+b+c)(x+y+z) \\ w(-1) &&= w_4 -w_3+w_2-w_1+w_0 &&= (a-b+c)(x-y+z) \\ w(-2) &&= 16w_4-8w_3+4w_2-2w_1+w_0 &&= (4a-2b+c)(4x-2y+z)\\ w(\infty) &&= w_4 &&= ax \end{array} $$ Así vemos que sólo se necesitan 5 multiplicaciones de esas sumas específicas y ya casi estamos.

Para acelerar las cosas, vamos a utilizar la representación matricial de las ecuaciones anteriores:

$$ \begin{pmatrix} w(0) \\ w(1) \\ w(-1)\\ w(-2)\\ w(\infty) \end{pmatrix} = \begin{pmatrix} 1 && 0 && 0 && 0 && 0 \\ 1 && 1 && 1 && 1 && 1 \\ 1 && -1 && 1 && -1 && 1 \\ 16 && -8 && 4 && -2 && 1 \\ 0 && 0 && 0 && 0 && 1 \end{pmatrix} \cdot \begin{pmatrix} w_0 \\ w_1 \\ w_2 \\ w_3 \\ w_4 \end{pmatrix} $$

Usando la inversa de esta matriz (tomada directamente de Wikipedia):

$$ \begin{pmatrix} w_0 \\ w_1 \\ w_2 \\ w_3 \\ w_4 \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 \\ 1/2 & 1/3 & -1 & 1/6 & -2 \\ -1 & 1/2 & 1/2 & 0 & -1 \\ -1/2 & 1/6 & 1/2 & -1/6 & 2 \\ 0 & 0 & 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} w(0) \\ w(1) \\ w(-1) \\ w(-2) \\ w(\infty) \end{pmatrix} $$ Lo que nos lleva a: $$ \begin{array}[b]{l} w_0 = cz \\ w_1 = \frac {w(0)} 2 + \frac {w(1)} 3 - w(-1) + \frac {w(-2)} 6 -2 w(\infty) \\ w_2 = -w(0) + \frac {w(1)} 2 + \frac {w(-1)} 2 - w(\infty) \\ w_3 = -\frac{w(0)} 2 + \frac{w(1)} 6 + \frac{w(-1)} 2 - \frac{w(-2)} 6 + 2 w(\infty) \\ w_4 = ax \end{array} $$ Y por último: $$ \begin{array}[b]{l} w_0 = cz \\ w_1 = \frac {cz} 2 + \frac {(a+b+c)(x+y+z)} 3 - (a-b+c)(x-y+z) + \frac {(4a-2b+c)(4x-2y+z)} 6 -2 ax \\ w_2 = -cz + \frac {(a+b+c)(x+y+z)} 2 + \frac {(a-b+c)(x-y+z)} 2 - ax \\ w_3 = -\frac{cz} 2 + \frac{(a+b+c)(x+y+z)} 6 + \frac{(a-b+c)(x-y+z)} 2 - \frac{(4a-2b+c)(4x-2y+z)} 6 + 2 ax \\ w_4 = ax \end{array} $$

Editar:

Para aquellos que quieran usar esas ecuaciones como soporte para alguna programación (como yo mismo - necesitaba esto para mi propia clase de enteros de 96 bits):

  1. Tenga en cuenta el desbordamiento - especialmente con la adición, ya que puede ser fácilmente pasado por alto, pero sucederá - especialmente cuando se suman 3 segmentos con multiplicadores como 16, etc.

  2. Un coste bastante importante (algorítmicamente hablando) es la división aquí - aunque será "división exacta" (ver en la biblioteca matemática GMP) por lo que significa que siempre saldrá sin ningún recordatorio (por lo que es más barato) y puede ser precalculado (ya sea por el compilador o tú en ensamblador o lo que sea)

  3. Puede intentar experimentar con diferentes puntos de interpolación para obtener números de división/multiplicación "más adecuados", aunque ir más allá de 8/-8 parece poco práctico, ya que alcanzará rápidamente los límites de desbordamiento o perjudicará la precisión (depende de si se trata de números enteros o en coma flotante)

PS. Por favor, indíqueme cualquier error que haya cometido, tanto en inglés como en las ecuaciones

0 votos

Esta es posiblemente la respuesta más elaborada que alguien me ha dado en el intercambio de pilas. :| kudos, karma, upvote, todo para usted señor.

0 votos

Gracias :) En realidad era un problema (5 multiplicaciones sobre un número de 3 dígitos) con el que estaba luchando también y tu pregunta aparece bastante arriba en las búsquedas. Así que he decidido devolver a esas pobres almas cuando he utilizado el conocimiento de otras personas (wikipedia). Por favor, tomen esas ecuaciones con un grano de sal ya que no tuve tiempo de comprobarlas.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X