Articulo de referencia

Algoritmo de multiplicación

Un algoritmo de multiplicación es un método para multiplicar dos números. Dependiendo de la magnitud de los números, algunos algoritmos son más eficientes que otros. Se conocen ...

Un algoritmo de multiplicación es un método para multiplicar dos números. Dependiendo de la magnitud de los números, algunos algoritmos son más eficientes que otros. Se conocen numerosos algoritmos y se ha investigado mucho sobre el tema.

El método más antiguo y sencillo, conocido desde la antigüedad como multiplicación larga o multiplicación escolar , consiste en multiplicar cada dígito del primer número por cada dígito del segundo y sumar los resultados. Esto tiene una complejidad temporal deO(norte2){\displaystyle O(n^{2})}donde n es el número de dígitos. Cuando se realiza manualmente, también se puede reformular como multiplicación por método de cuadrícula o multiplicación reticular . En software, se puede denominar "desplazamiento y suma" debido a que solo se requieren desplazamientos de bits y suma.

En 1960, Anatoly Karatsuba descubrió la multiplicación de Karatsuba , lo que desencadenó una oleada de investigaciones sobre algoritmos de multiplicación rápidos. Este método utiliza tres multiplicaciones en lugar de cuatro para multiplicar dos números de dos dígitos. (Una variante de este método también se puede utilizar para multiplicar números complejos rápidamente). Realizado de forma recursiva , tiene una complejidad temporal deO(norteregistro23){\displaystyle O(n^{\log _{2}3})}Al dividir los números en más de dos partes, se obtiene la multiplicación de Toom-Cook ; por ejemplo, al usar tres partes, se obtiene el algoritmo Toom-3 . Si bien usar muchas partes permite que el exponente se acerque arbitrariamente a 1, el factor constante también aumenta, lo que lo hace poco práctico.

En 1968, se descubrió el algoritmo de Schönhage-Strassen , que utiliza una transformada de Fourier sobre un módulo . Tiene una complejidad temporal deO(norteregistronorteregistroregistronorte){\displaystyle O(n\log n\log \log n)}En 2007, Martin Fürer propuso un algoritmo con complejidadO(norteregistronorte2Θ(registronorte)){\displaystyle O(n\log n2^{\Theta (\log ^{*}n)})}. En 2014, Harvey, Joris van der Hoeven y Lecerf propusieron uno con complejidadO(norteregistronorte23registronorte){\displaystyle O(n\log n2^{3\log ^{*}n})}, haciendo así explícita la constante implícita ; esto se mejoró paraO(norteregistronorte22registronorte){\displaystyle O(n\log n2^{2\log ^{*}n})}en 2018. Por último, en 2019, Harvey y van der Hoeven idearon un algoritmo galáctico con complejidadO(norteregistronorte){\displaystyle O(n\log n)}Esto coincide con la suposición de Schönhage y Strassen de que este sería el límite óptimo, aunque esto sigue siendo una conjetura hoy en día.

Los algoritmos de multiplicación de enteros también pueden utilizarse para multiplicar polinomios mediante el método de sustitución de Kronecker .

Multiplicación larga

Si se utiliza un sistema de numeración posicional , en las escuelas se enseña una forma natural de multiplicar números , conocida como multiplicación larga , a veces llamada multiplicación escolar o algoritmo estándar : se multiplica el multiplicando por cada dígito del multiplicador y luego se suman todos los resultados correctamente desplazados. Requiere memorizar la tabla de multiplicar de un solo dígito.

Este es el algoritmo habitual para multiplicar números grandes a mano en base 10. Una persona que realiza multiplicaciones largas en papel anotará todos los productos y luego los sumará; un usuario de ábaco sumará los productos tan pronto como calcule cada uno.

Ejemplo

Este ejemplo utiliza la multiplicación larga para multiplicar 23.958.233 (multiplicando) por 5.830 (multiplicador) y llega a 139.676.498.390 como resultado (producto).

 23958233 × 5830 ——————————————— 00000000 ( = 23.958.233 × 0) 71874699 ( = 23.958.233 × 30) 191665864 ( = 23.958.233 × 800) + 119791165 ( = 23.958.233 × 5.000) ——————————————— 139676498390 ( = 139.676.498.390)

Otras anotaciones

En algunos países como Alemania , la multiplicación anterior se representa de forma similar, pero con el producto original en posición horizontal y el cálculo comenzando con el primer dígito del multiplicador: [ 1 ]

23958233 · 5830 ——————————————— 119791165 191665864 71874699 00000000 ——————————————— 139676498390

El siguiente pseudocódigo describe el proceso de la multiplicación anterior. Conserva una sola fila para mantener la suma, que finalmente se convierte en el resultado. Nótese que el operador '+=' se utiliza para indicar la suma a un valor existente y para almacenar la operación (similar a lenguajes como Java y C) para mayor concisión.

multiplicar ( a [ 1 .. p ] , b [ 1 .. q ] , base ) // Operandos que contienen los dígitos más a la derecha en el índice 1producto = [ 1 .. p + q ] // Asignar espacio para el resultadopara b_i = 1 a q // para todos los dígitos en bacarreo = 0para a_i = 1 a p // para todos los dígitos en aproducto [ a_i + b_i - 1 ] += acarreo + a [ a_i ] * b [ b_i ]acarreo = producto [ a_i + b_i - 1 ] / baseproducto [ a_i + b_i - 1 ] = producto [ a_i + b_i - 1 ] mod baseproducto [ b_i + p ] = acarreo // el último dígito proviene del acarreo finalproducto de devolución

Uso en computadoras

Algunos chips implementan la multiplicación larga, ya sea en hardware o en microcódigo , para diversos tamaños de palabra de enteros y coma flotante. En aritmética de precisión arbitraria , es común usar la multiplicación larga con la base establecida en 2w , donde w es el número de bits en una palabra, para multiplicar números relativamente pequeños. Para multiplicar dos números de n dígitos usando este método, se necesitan aproximadamente operaciones. De manera más formal, multiplicar dos números de n dígitos usando la multiplicación larga requiere Θ ( n² ) operaciones de un solo dígito (sumas y multiplicaciones).

Cuando se implementan en software, los algoritmos de multiplicación largos deben manejar el desbordamiento durante las sumas, lo cual puede ser costoso. Una solución típica es representar el número en una base pequeña, b , de modo que, por ejemplo, 8 b sea un entero representable por la máquina. De esta manera, se pueden realizar varias sumas antes de que ocurra un desbordamiento. Cuando el número se vuelve demasiado grande, se agrega una parte al resultado, o se realiza un acarreo y se asigna la parte restante a un número menor que b . Este proceso se denomina normalización . Richard Brent utilizó este enfoque en su paquete de Fortran, MP. [ 2 ]

Inicialmente, las computadoras utilizaban un algoritmo muy similar a la multiplicación larga en base 2, pero los procesadores modernos han optimizado los circuitos para multiplicaciones rápidas mediante algoritmos más eficientes, a costa de una implementación de hardware más compleja. En base dos, la multiplicación larga a veces se denomina "desplazamiento y suma" , porque el algoritmo se simplifica y consiste simplemente en desplazar a la izquierda (multiplicar por potencias de dos) y sumar. La mayoría de los microprocesadores disponibles actualmente implementan este u otros algoritmos similares (como la codificación Booth ) para diversos tamaños de enteros y coma flotante en multiplicadores de hardware o en microcódigo .

En los procesadores actuales, una instrucción de desplazamiento de bits suele ser (aunque no siempre) más rápida que una instrucción de multiplicación y puede utilizarse para multiplicar (desplazamiento a la izquierda) y dividir (desplazamiento a la derecha) por potencias de dos. La multiplicación y la división por una constante pueden implementarse mediante una secuencia de desplazamientos y sumas o restas. Por ejemplo, existen varias maneras de multiplicar por 10 utilizando únicamente desplazamiento de bits y suma.

(( x << 2 ) + x ) << 1 # Aquí 10*x se calcula como (x*2^2 + x)*2 ( x << 3 ) + ( x << 1 ) # Aquí 10*x se calcula como x*2^3 + x*2

En algunos casos, tales secuencias de desplazamientos y sumas o restas superarán a los multiplicadores de hardware y especialmente a los divisores. Una división por un número de la forma2norte{\displaystyle 2^{n}}o2norte±1{\displaystyle 2^{n}\pm 1}A menudo se puede convertir en una secuencia tan corta.

Algoritmos para la multiplicación manual

Además de la multiplicación larga estándar, existen otros métodos para realizar multiplicaciones a mano. Estos algoritmos pueden diseñarse para agilizar el proceso, facilitar los cálculos o con fines didácticos, especialmente cuando no se dispone de ordenadores ni de tablas de multiplicar .

Método de cuadrícula

El método de la cuadrícula (o método de la caja) es un método introductorio para la multiplicación de números de varias cifras que se suele enseñar a los alumnos de primaria . Forma parte del currículo nacional de matemáticas de primaria en Inglaterra y Gales desde finales de la década de 1990. [ 3 ]

Ambos factores se dividen ("particionan") en sus partes de centenas, decenas y unidades, y luego se calculan explícitamente los productos de las partes en una etapa de multiplicación relativamente simple, antes de que estas contribuciones se sumen para dar la respuesta final en una etapa de suma separada.

El cálculo 34 × 13, por ejemplo, podría realizarse utilizando la cuadrícula:

 300 40 90 + 12 ———— 442

seguido de la suma para obtener 442, ya sea en una sola suma (ver a la derecha) o mediante la formación de los totales fila por fila.

(300 + 40) + (90 + 12) = 340 + 102 = 442.

Este método de cálculo (aunque no necesariamente con la disposición explícita de la cuadrícula) también se conoce como algoritmo de productos parciales . Su esencia radica en el cálculo de las multiplicaciones simples por separado, dejando todas las sumas para la etapa final de agregación.

En principio, el método de la cuadrícula puede aplicarse a factores de cualquier tamaño, aunque el número de subproductos se vuelve engorroso a medida que aumenta el número de dígitos. No obstante, se considera un método explícito y útil para introducir la idea de las multiplicaciones de varios dígitos; y, en una época en la que la mayoría de los cálculos de multiplicación se realizan con una calculadora o una hoja de cálculo , en la práctica puede ser el único algoritmo de multiplicación que algunos estudiantes necesiten.

Multiplicación reticular

Primero, configura la cuadrícula marcando sus filas y columnas con los números que se van a multiplicar. Luego, rellena las casillas con las cifras de las decenas en los triángulos superiores y las cifras de las unidades en los triángulos inferiores.
Finalmente, suma a lo largo de las diagonales y lleva según sea necesario para obtener la respuesta.

La multiplicación reticular, o por criba, es algorítmicamente equivalente a la multiplicación larga. Requiere la preparación de una retícula (una cuadrícula dibujada en papel) que guía el cálculo y separa todas las multiplicaciones de las sumas . Fue introducida en Europa en 1202 en el Liber Abaci de Fibonacci . Fibonacci describió la operación como mental, usando sus manos derecha e izquierda para llevar a cabo los cálculos intermedios. Matrakçı Nasuh presentó 6 variantes diferentes de este método en su libro del siglo XVI, Umdet-ul Hisab. Fue ampliamente utilizado en las escuelas Enderun de todo el Imperio Otomano. [ 4 ] Los huesos de Napier , o varillas de Napier, también usaban este método, como publicó Napier en 1617, el año de su muerte.

Como se muestra en el ejemplo, el multiplicando y el multiplicador se escriben encima y a la derecha de una cuadrícula o tamiz. Se encuentra en la "Aritmética" de Muhammad ibn Musa al-Khwarizmi , una de las fuentes de Leonardo mencionadas por Sigler, autor de "El Liber Abaci de Fibonacci" (2002).

  • Durante la fase de multiplicación, la cuadrícula se rellena con productos de dos dígitos de los dígitos correspondientes que etiquetan cada fila y columna: el dígito de las decenas se coloca en la esquina superior izquierda.
  • Durante la fase de adición, la red se suma en las diagonales.
  • Finalmente, si es necesaria una fase de acarreo, la respuesta que se muestra a lo largo de los lados izquierdo e inferior de la cuadrícula se convierte a la forma normal llevando los dígitos de las decenas como en la suma o multiplicación larga.

Ejemplo

Las imágenes de la derecha muestran cómo calcular 345 × 12 usando la multiplicación reticular. Como ejemplo más complejo, considere la imagen de abajo que muestra el cálculo de 23.958.233 multiplicado por 5.830 (multiplicador); el resultado es 139.676.498.390. Observe que 23.958.233 está en la parte superior de la cuadrícula y 5.830 en el lado derecho. Los productos llenan la cuadrícula y la suma de esos productos (en la diagonal) está en los lados izquierdo e inferior. Luego, esas sumas se totalizan como se muestra.

multiplicación campesina rusa

El método binario también se conoce como multiplicación campesina, porque ha sido ampliamente utilizado por personas clasificadas como campesinas y, por lo tanto, no han memorizado las tablas de multiplicar necesarias para la multiplicación larga. [ 5 ] El algoritmo se utilizaba en el antiguo Egipto. [ 6 ] Sus principales ventajas son que se puede enseñar rápidamente, no requiere memorización y se puede realizar utilizando fichas, como fichas de póker , si no se dispone de papel y lápiz. La desventaja es que requiere más pasos que la multiplicación larga, por lo que puede resultar engorroso para números grandes.

Descripción

Una columna contiene los números que resultan de dividir repetidamente el multiplicador por la mitad, ignorando el resto. Otra columna contigua contiene los resultados de duplicar repetidamente el multiplicando. El producto se calcula tachando cada fila donde el primer número termina en un dígito par y sumando los números restantes en la segunda columna para obtener el producto.

Ejemplos

Este ejemplo utiliza la multiplicación tradicional para multiplicar 11 por 3 y obtener un resultado de 33.

Decimal: Binario: 11 3 1011 11 5 6 101 110 2 12 10 1100 1 24 1 11000 ——————— 33 100001

Describir los pasos explícitamente:

  • En la parte superior están escritos los números 11 y 3.
  • 11 se divide por la mitad (5,5) y 3 se duplica (6). La parte fraccionaria se descarta (5,5 se convierte en 5).
  • El 5 se divide por la mitad (2,5) y el 6 se duplica (12). La parte fraccionaria se descarta (2,5 se convierte en 2). La cifra de la columna izquierda (2) es par , por lo que la cifra de la columna derecha (12) se descarta.
  • 2 se divide por la mitad (1) y 12 se duplica (24).
  • Se suman todos los valores que no se han tachado: 3 + 6 + 24 = 33.

El método funciona porque la multiplicación es distributiva , por lo tanto:

3×11=3×(1×20+1×21+0×22+1×23)=3×(1+2+8)=3+6+24=33.{\displaystyle {\begin{aligned}3\times 11&=3\times (1\times 2^{0}+1\times 2^{1}+0\times 2^{2}+1\times 2^{3})\\&=3\times (1+2+8)\\&=3+6+24\\&=33.\end{aligned}}}

Un ejemplo más complejo, utilizando las cifras de los ejemplos anteriores (23.958.233 y 5.830):

Decimal: Binario: 5830 23958233 1011011000110 1011011011001001011011001 2915 47916466 101101100011 10110110110010010110110010 1457 95832932 10110110001 101101101100100101101100100 728 191665864 1011011000 1011011011001001011011001000 364 383331728 101101100 10110110110010010110110010000 182 766663456 10110110 101101101100100101101100100000 91 1533326912 1011011 1011011011001001011011001000000 45 3066653824 101101 10110110110010010110110010000000 22 6133307648 10110 101101101100100101101100100000000 11 12266615296 1011 1011011011001001011011001000000000 5 24533230592 101 10110110110010010110110010000000000 2 49066461184 10 101101101100100101101100100000000000 1 98132922368 1 1011011011001001011011001000000000000 ———————————— 1022143253354344244353353243222210110 (antes de llevar) 139676498390 10000010000101010111100011100111010110

multiplicación de cuartos de cuadrado

En algunos casos, esta fórmula puede utilizarse para facilitar la realización de tareas de multiplicación:

(incógnita+y)24(incógnitay)24=(incógnita+y2)2(incógnitay2)2=incógnitay{\displaystyle {\frac {\left(x+y\right)^{2}}{4}}-{\frac {\left(xy\right)^{2}}{4}}=\left({\frac {x+y}{2}}\right)^{2}-\left({\frac {xy}{2}}\right)^{2}=xy}

En el caso dondeincógnita{\displaystyle x}yy{\displaystyle y}son enteros, tenemos que

(incógnita+y)2(incógnitay)2mod4{\displaystyle (x+y)^{2}\equiv (xy)^{2}{\bmod {4}}}

porqueincógnita+y{\displaystyle x+y}yincógnitay{\displaystyle xy}son ambos pares o ambos impares. Esto significa que

incógnitay=14(incógnita+y)214(incógnitay)2=((incógnita+y)2 div 4)((incógnitay)2 div 4){\displaystyle {\begin{aligned}xy&={\frac {1}{4}}(x+y)^{2}-{\frac {1}{4}}(xy)^{2}\\&=\left((x+y)^{2}{\text{ div }}4\right)-\left((xy)^{2}{\text{ div }}4\right)\end{aligned}}}

y es suficiente con (pre)calcular la parte entera de los cuadrados divididos por 4 como en el siguiente ejemplo.

Ejemplos

A continuación se muestra una tabla de consulta de cuartos de cuadrado con el resto descartado para los dígitos del 0 al 18; esto permite la multiplicación de números hasta 9×9 .

Por ejemplo, al multiplicar 9 por 3, la suma y la diferencia de esos números dan como resultado 12 y 6 respectivamente. Al buscar ambos valores en la tabla, obtenemos 36 y 9, cuya diferencia es 27, que es el producto de 9 y 3.

Historia de la multiplicación por cuartos de cuadrado

En la época prehistórica, la multiplicación de un cuarto de cuadrado implicaba la función piso ; que algunas fuentes [ 7 ] [ 8 ] atribuyen a las matemáticas babilónicas (2000–1600 a. C.).

Antoine Voisin publicó una tabla de cuartos de cuadrado del 1 al 1000 en 1817 como ayuda para la multiplicación. Samuel Laundy publicó una tabla más extensa de cuartos de cuadrado del 1 al 100000 en 1856, [ 9 ] y Joseph Blater publicó una tabla del 1 al 200000 en 1888. [ 10 ]

En las computadoras analógicas, se utilizaban multiplicadores de cuarto de cuadrado para generar una señal analógica producto de dos señales de entrada analógicas. En esta aplicación, la suma y la diferencia de dos voltajes de entrada se obtienen mediante amplificadores operacionales . El cuadrado de cada uno de estos se aproxima mediante circuitos lineales por tramos . Finalmente, se calcula la diferencia de los dos cuadrados y se multiplica por un cuarto utilizando otro amplificador operacional.

En 1980, Everett L. Johnson propuso utilizar el método del cuarto de cuadrado en un multiplicador digital . [ 11 ] Para formar el producto de dos enteros de 8 bits, por ejemplo, el dispositivo digital forma la suma y la diferencia, busca ambas cantidades en una tabla de cuadrados, toma la diferencia de los resultados y divide por cuatro desplazando dos bits a la derecha. Para enteros de 8 bits, la tabla de cuartos de cuadrado tendrá 2 9 1=511 entradas (una entrada para el rango completo 0..510 de sumas posibles, las diferencias usando solo las primeras 256 entradas en el rango 0..255) o 2 9 1=511 entradas (usando para diferencias negativas la técnica de complementos a 2 y enmascaramiento de 9 bits, que evita probar el signo de las diferencias), cada entrada siendo de 16 bits de ancho (los valores de entrada son de (0²/4)=0 a (510²/4)=65025).

La técnica del multiplicador de cuarto de cuadrado ha beneficiado a los sistemas de 8 bits que no tienen soporte para un multiplicador de hardware. Charles Putney la implementó para el 6502. [ 12 ]

Complejidad computacional de la multiplicación

Problema sin resolver en informática
¿Cuál es el algoritmo más rápido para la multiplicación de dos?norte{\displaystyle n}¿Números de -dígitos?

Una línea de investigación en la ciencia de la computación teórica trata sobre el número de operaciones aritméticas de un solo bit necesarias para multiplicar dosnorte{\displaystyle n}enteros de bits. Esto se conoce como la complejidad computacional de la multiplicación. Los algoritmos habituales realizados a mano tienen una complejidad asintótica deO(norte2){\displaystyle O(n^{2})}, pero en 1960 Anatoly Karatsuba descubrió que era posible una mayor complejidad (con el algoritmo de Karatsuba ). [ 13 ]

Actualmente, el algoritmo con la mejor complejidad computacional es un algoritmo de 2019 de David Harvey y Joris van der Hoeven , que utiliza las estrategias de usar transformaciones de teoría de números introducidas con el algoritmo de Schönhage-Strassen para multiplicar enteros usando soloO(norteregistronorte){\displaystyle O(n\log n)}operaciones. [ 14 ] Se conjetura que este es el mejor algoritmo posible, pero los límites inferiores deΩ(norteregistronorte){\displaystyle \Omega (n\log n)}no se conocen.

Multiplicación de Karatsuba

La multiplicación de Karatsuba es un algoritmo de divide y vencerás O( n log 2 3 ) ≈ O( n 1.585 ) que utiliza recursión para fusionar subcálculos.

Al reescribir la fórmula, se posibilita realizar subcálculos/recursión. Mediante la recursión, se puede resolver esto de forma rápida.

Dejarincógnita{\displaystyle x}yy{\displaystyle y}ser representado comonorte{\displaystyle n}-cadenas de dígitos en alguna baseB{\displaystyle B}Para cualquier entero positivometro{\displaystyle m}menos quenorte{\displaystyle n}, se pueden escribir los dos números dados como

incógnita=incógnita1Bmetro+incógnita0,{\displaystyle x=x_{1}B^{m}+x_{0},}
y=y1Bmetro+y0,{\displaystyle y=y_{1}B^{m}+y_{0},}

dóndeincógnita0{\displaystyle x_{0}}yy0{\displaystyle y_{0}}son menos queBmetro{\displaystyle B^{m}}El producto es entonces

incógnitay=(incógnita1Bmetro+incógnita0)(y1Bmetro+y0)=incógnita1y1B2metro+(incógnita1y0+incógnita0y1)Bmetro+incógnita0y0=z2B2metro+z1Bmetro+z0,{\displaystyle {\begin{aligned}xy&=(x_{1}B^{m}+x_{0})(y_{1}B^{m}+y_{0})\\&=x_{1}y_{1}B^{2m}+(x_{1}y_{0}+x_{0}y_{1})B^{m}+x_{0}y_{0}\\&=z_{2}B^{2m}+z_{1}B^{m}+z_{0},\\\end{aligned}}}

dónde

z2=incógnita1y1,{\displaystyle z_{2}=x_{1}y_{1},}
z1=incógnita1y0+incógnita0y1,{\ Displaystyle z_ {1} = x_ {1} y_ {0} + x_ {0} y_ {1},}
z0=incógnita0y0.{\displaystyle z_{0}=x_{0}y_{0}.}

Estas fórmulas requieren cuatro multiplicaciones y eran conocidas por Charles Babbage . [ 15 ] Karatsuba observó queincógnitay{\displaystyle xy}se puede calcular en solo tres multiplicaciones, a costa de algunas sumas adicionales. Conz0{\displaystyle z_{0}}yz2{\displaystyle z_{2}}como antes se puede observar que

z1=incógnita1y0+incógnita0y1=incógnita1y0+incógnita0y1+incógnita1y1incógnita1y1+incógnita0y0incógnita0y0=incógnita1y0+incógnita0y0+incógnita0y1+incógnita1y1incógnita1y1incógnita0y0=(incógnita1+incógnita0)y0+(incógnita0+incógnita1)y1incógnita1y1incógnita0y0=(incógnita1+incógnita0)(y0+y1)incógnita1y1incógnita0y0=(incógnita1+incógnita0)(y1+y0)z2z0.{\displaystyle {\begin{aligned}z_{1}&=x_{1}y_{0}+x_{0}y_{1}\\&=x_{1}y_{0}+x_{0}y_{1}+x_{1}y_{1}-x_{1}y_{ 1}+x_{0}y_{0}-x_{0}y_{0}\\&=x_{1}y_{0}+x_{0}y_{0}+x_{0}y_{1}+x_{1}y_{1}-x_{1}y_{1}-x_{0}y _{0}\\&=(x_{1}+x_{0})y_{0}+(x_{0}+x_{1})y_{1}-x_{1}y_{1}-x_{0}y_{0}\\&=(x_{1}+x_{0})(y_{0}+y_{1})-x_{1}y_{1}-x_{0}y_{0}\\&=(x_{1}+x_{0})(y_{1}+y_{0})-z_{2}-z_{0}.\\\end{aligned}}}

Debido a la sobrecarga de la recursión, la multiplicación de Karatsuba es más lenta que la multiplicación larga para valores pequeños de n ; por lo tanto, las implementaciones típicas cambian a la multiplicación larga para valores pequeños de n .

Caso general con multiplicación de N números

Al analizar los patrones tras la expansión, se observa lo siguiente:

(incógnita1Bmetro+incógnita0)(y1Bmetro+y0)(z1Bmetro+z0)(a1Bmetro+a0)=a1incógnita1y1z1B4metro+a1incógnita1y1z0B3metro+a1incógnita1y0z1B3metro+a1incógnita0y1z1B3metro+a0incógnita1y1z1B3metro+a1incógnita1y0z0B2metro+a1incógnita0y1z0B2metro+a0incógnita1y1z0B2metro+a1incógnita0y0z1B2metro+a0incógnita1y0z1B2metro+a0incógnita0y1z1B2metro+a1incógnita0y0z0Bmetro1+a0incógnita1y0z0Bmetro1+a0incógnita0y1z0Bmetro1+a0incógnita0y0z1Bmetro1+a0incógnita0y0z0B1metro{\displaystyle {\begin{alignedat}{5}(x_{1}B^{m}+x_{0})(y_{1}B^{m}+y_{0})(z_{1}B^{m}+z_{0})(a_{1}B^{m}+a_{0})&=a_{1}x_{1}y_{1} z_{1}B^{4m}&+a_{1}x_{1}y_{1}z_{0}B^{3m}&+a_{1}x_{1}y_{0}z_{1}B^{3m}&+a_{1}x_{0}y_{1}z_{1}B^{3m}\\&+a_{0}x_{1}y _{1}z_{1}B^{3m}&+a_{1}x_{1}y_{0}z_{0}B^{2m}&+a_{1}x_{0}y_{1}z_{0}B^{2m}&+a_{0}x_{1}y_{1}z_{0}B^{2m}\\&+a_{1}x_{0}y_{0}z_{1}B^{2m}&+a_{0}x_{1}y_{0}z_{1}B^{2m}&+a_{0}x_{0}y_{1}z_{1}B^{2m}&+a_{1}x_{0}y_{0}z_{0}B^{m{\phantom {1}}}\\&+a_{0}x_{1}y_{0}z_{0}B^{m{\phantom {1}}}&+a_{0}x_{0}y_{1}z_{0}B^{m{\phantom {1}}}&+a_{0}x_{0}y_{0}z_{1}B^{m{\phantom {1}}}&+a_{0}x_{0}y_{0}z_{0}{\phantom {B^{1m}}}\end{alignedat}}}

Cada sumando está asociado a un número binario único del 0 al 2norte+11{\displaystyle 2^{N+1}-1}, Por ejemploa1incógnita1y1z11111, a1incógnita0y1z01010{\displaystyle a_{1}x_{1}y_{1}z_{1}\longleftrightarrow 1111,\ a_{1}x_{0}y_{1}z_{0}\longleftrightarrow 1010}etc. Además; B se eleva a la potencia de 1, en esta cadena binaria, multiplicado por m.

Si lo expresamos en menos términos, obtenemos:

j=1norte(incógnitaj,1Bmetro+incógnitaj,0)=i=12norte+11j=1norteincógnitaj,do(i,j)Bmetroj=1nortedo(i,j)=j=0nortezjBjmetro{\displaystyle \prod _{j=1}^{N}(x_{j,1}B^{m}+x_{j,0})=\sum _{i=1}^{2^{N+1}-1}\prod _{j=1}^{N}x_{j,c(i,j)}B^{m\sum _{j=1}^{N}c(i,j)}=\sum _{j=0}^{N}z_{j}B^{jm}}, dóndedo(i,j){\displaystyle c(i,j)}significa dígito en el número i en la posición j. Observe quedo(i,j){0,1}{\displaystyle c(i,j)\in \{0,1\}}

z0=j=1norteincógnitaj,0znorte=j=1norteincógnitaj,1znorte1=j=1norte(incógnitaj,0+incógnitaj,1)inorte1nortezi{\displaystyle {\begin{aligned}z_{0}&=\prod _{j=1}^{N}x_{j,0}\\z_{N}&=\prod _{j=1}^{N}x_{j,1}\\z_{N-1}&=\prod _{j=1}^{N}(x_{j,0}+x_{j,1})-\sum _{i\neq N-1}^{N}z_{i}\end{aligned}}}

Historia

El algoritmo de Karatsuba fue el primer algoritmo conocido para la multiplicación que es asintóticamente más rápido que la multiplicación larga, [ 16 ] y por lo tanto puede considerarse como el punto de partida para la teoría de las multiplicaciones rápidas.

Toom-Cook

Otro método de multiplicación se denomina Toom-Cook o Toom-3. Este método divide cada número a multiplicar en varias partes. El método Toom-Cook es una generalización del método Karatsuba. Un método Toom-Cook de tres partes puede realizar una multiplicación de tamaño 3N con el coste de cinco multiplicaciones de tamaño N. Esto acelera la operación en un factor de 9/5, mientras que el método Karatsuba la acelera en un factor de 4/3.

Si bien el uso de más partes puede reducir aún más el tiempo dedicado a las multiplicaciones recursivas, la sobrecarga derivada de las sumas y la gestión de dígitos también aumenta. Por esta razón, el método de transformadas de Fourier suele ser más rápido para números con varios miles de dígitos, y asintóticamente más rápido para números aún mayores.

Schönhage–Strassen

Demostración de la multiplicación de 1234 × 5678 = 7006652 mediante transformadas rápidas de Fourier (FFT). Se utilizan transformadas de teoría de números en los enteros módulo 337, seleccionando 85 como raíz octava de la unidad. Se emplea la base 10 en lugar de la base 2 w con fines ilustrativos.

Todo número en base B se puede escribir como un polinomio:

incógnita=i=0norteincógnitaiBi{\displaystyle X=\sum _{i=0}^{N}{x_{i}B^{i}}}

Además, la multiplicación de dos números podría considerarse como el producto de dos polinomios:

incógnitaY=(i=0norteincógnitaiBi)(j=0norteyiBj){\displaystyle XY=(\sum _{i=0}^{N}{x_{i}B^{i}})\,(\sum _{j=0}^{N}{y_{i}B^{j}})}

Dado que el coeficiente deBk{\displaystyle B^{k}}en el producto eszk=(i,j):i+j=kincógnitaiyj=i=0kincógnitaiyki,{\displaystyle z_{k}=\sum _{(i,j):i+j=k}{x_{i}y_{j}}=\sum _{i=0}^{k}{x_{i}y_{k-i}},} Se puede utilizar una convolución o la transformada rápida de Fourier (FFT): F^(incógnitaY)=F^(i=0kincógnitaiyki)=F^(incógnita)F^(Y).{\displaystyle {\hat {f}}(XY)={\hat {f}}(\sum _{i=0}^{k}{x_{i}y_{k-i}})={\hat {f}}(X)\cdot {\hat {f}}(Y).}

Por lo tanto, la multiplicación se reduce a una FFT ,norte{\displaystyle N}multiplicaciones y una FFT inversa. El resultado es una complejidad temporal de O ( n  log( n  ) log (log n )) .

Historia

El algoritmo fue inventado por Strassen (1968). En 1971, Schönhage y Strassen proporcionaron garantías prácticas y teóricas, dando como resultado el algoritmo de Schönhage-Strassen . [ 17 ]

Mejoras adicionales

En 2007, el matemático suizo Martin Fürer, de la Universidad Estatal de Pensilvania, mejoró la complejidad asintótica de la multiplicación de enteros.O(norteregistronorte2Θ(registro(norte))){\textstyle O(n\log n\cdot {2}^{\Theta (\log ^{*}(n))})}usando transformadas de Fourier sobre números complejos , [ 18 ] donde log * denota el logaritmo iterado . Anindya De, Chandan Saha, Piyush Kurur y Ramprasad Saptharishi dieron un algoritmo similar usando aritmética modular en 2008 logrando el mismo tiempo de ejecución. [ 19 ] En el contexto del material anterior, lo que estos últimos autores han logrado es encontrar N mucho menor que 2 3 k + 1, de modo que Z / NZ tenga una raíz (2 m )-ésima de la unidad. Esto acelera el cálculo y reduce la complejidad temporal. Sin embargo, estos últimos algoritmos solo son más rápidos que Schönhage–Strassen para entradas impracticablemente grandes.

En 2014, Harvey, Joris van der Hoeven y Lecerf [ 20 ] presentaron un nuevo algoritmo que logra un tiempo de ejecución deO(norteregistronorte23registronorte){\displaystyle O(n\log n\cdot 2^{3\log ^{*}n})}, haciendo explícita la constante implícita en laO(registronorte){\displaystyle O(\log ^{*}n)}exponente. También propusieron una variante de su algoritmo que lograO(norteregistronorte22registronorte){\displaystyle O(n\log n\cdot 2^{2\log ^{*}n})}pero cuya validez se basa en conjeturas estándar sobre la distribución de los primos de Mersenne . En 2016, Covanov y Thomé propusieron un algoritmo de multiplicación de enteros basado en una generalización de los primos de Fermat que, según conjeturas, alcanza un límite de complejidad deO(norteregistronorte22registronorte){\displaystyle O(n\log n\cdot 2^{2\log ^{*}n})}Esto coincide con el resultado condicional de 2015 de Harvey, van der Hoeven y Lecerf, pero utiliza un algoritmo diferente y se basa en una conjetura diferente. [ 21 ] En 2018, Harvey y van der Hoeven utilizaron un enfoque basado en la existencia de vectores reticulares cortos garantizados por el teorema de Minkowski para demostrar una cota de complejidad incondicional deO(norteregistronorte22registronorte){\displaystyle O(n\log n\cdot 2^{2\log ^{*}n})}. [ 22 ]

En marzo de 2019, David Harvey y Joris van der Hoeven anunciaron su descubrimiento de un algoritmo de multiplicación O ( n log n ) . [ 23 ] Fue publicado en los Annals of Mathematics en 2021. [ 14 ] Debido a que Schönhage y Strassen predijeron que n  log( n ) es el resultado "mejor posible", Harvey dijo: "...  se espera que nuestro trabajo sea el final del camino para este problema, aunque todavía no sabemos cómo demostrarlo rigurosamente". [ 24 ] Sin embargo, el nuevo algoritmo es muy poco práctico: es más rápido que el algoritmo de Schönhage-Strassen solo si el número de dígitos excede [ 14 ]

2172912=27137398073256634897664758526207831206414.145331×10214857091104455254035802532723729912717102.148571×1038.{\displaystyle {\begin{aligned}2^{{1729}^{12}}&=2^{713\,739\,807\,325\,663\,489\,766\,475\,852\,620\,783\,120\,641}\\&\approx 4.145331\times 10^{214\,857\,091\,104\,455\,254\,035\,802\,532\,723\,729\,912\,717}\\&\approx 10^{2.148571\times 10^{38}}.\end{aligned}}}

límites inferiores

Existe una cota inferior trivial de Ω ( n ) para multiplicar dos números de n bits en un solo procesador; no se conoce ningún algoritmo equivalente (en máquinas convencionales, es decir, en máquinas equivalentes a Turing) ni ninguna cota inferior más precisa. La conjetura de Hartmanis-Stearns implicaría queO(norte){\displaystyle O(n)}no se puede lograr. La multiplicación está fuera de AC 0 [ p ] para cualquier primo p , lo que significa que no hay una familia de circuitos de profundidad constante y tamaño polinomial (o incluso subexponencial) que utilicen compuertas AND, OR, NOT y MOD p que puedan calcular un producto. Esto se deduce de una reducción de profundidad constante de MOD q a la multiplicación. [ 25 ] También se conocen cotas inferiores para la multiplicación para algunas clases de programas de ramificación . [ 26 ]

multiplicación de números complejos

La multiplicación compleja normalmente implica cuatro multiplicaciones y dos sumas.

(a+bi)(do+di)=(adobd)+(bdo+ad)i.{\displaystyle (a+bi)(c+di)=(ac-bd)+(bc+ad)i.}

O

×abidoadobdoidiadibd{\displaystyle {\begin{array}{c|c|c}\times &a&bi\\\hline c&ac&bci\\\hline di&adi&-bd\end{array}}}

Como observó Peter Ungar en 1963, se puede reducir el número de multiplicaciones a tres, utilizando esencialmente el mismo cálculo que el algoritmo de Karatsuba . [ 27 ] El producto ( a  + bi ) · ( c + di ) se puede calcular de la siguiente manera.   

k 1 = c · ( a + b )
k 2 = a · ( dc )
k 3 = b · ( c + d )
Parte real = k 1k 3
Parte imaginaria = k 1 + k 2 .

Este algoritmo utiliza solo tres multiplicaciones en lugar de cuatro, y cinco sumas o restas en lugar de dos. Si una multiplicación es más costosa que tres sumas o restas, como ocurre al calcular manualmente, entonces se obtiene una mejora en la velocidad. En las computadoras modernas, una multiplicación y una suma pueden tardar aproximadamente el mismo tiempo, por lo que es posible que no haya ninguna mejora en la velocidad. Existe una contrapartida: puede haber cierta pérdida de precisión al usar números de coma flotante.

Para las transformadas rápidas de Fourier (FFT) (o cualquier transformación lineal ), las multiplicaciones complejas se realizan mediante coeficientes constantes c  + di (denominados factores de rotación en las FFT), en cuyo caso dos de las sumas ( dc y c + d ) pueden precalcularse. Por lo tanto, solo se requieren tres multiplicaciones y tres sumas. [ 28 ] Sin embargo, intercambiar una multiplicación por una suma de esta manera puede que ya no sea beneficioso con las unidades de punto flotante modernas . [ 29 ] 

Multiplicación de polinomios

Todos los algoritmos de multiplicación anteriores también pueden extenderse a la multiplicación de polinomios . Alternativamente, se puede utilizar la técnica de sustitución de Kronecker para convertir el problema de multiplicar polinomios en una única multiplicación binaria. [ 30 ]

Los métodos de multiplicación largos pueden generalizarse para permitir la multiplicación de fórmulas algebraicas:

14ac - 3ab + 2 multiplicado por ac - ab + 1
14ac -3ab 2 ac -ab 1 ———————————————————— 14a 2 c 2 -3a 2 bc 2ac -14a 2 bc 3 a 2 b 2 -2ab 14ac -3ab 2 ——————————————————————————————————————— 14a 2 c 2 -17a 2 bc 16ac 3a 2 b 2 -5ab +2 ======================================= [ 31 ]

Como otro ejemplo de multiplicación basada en columnas, considere multiplicar 23 toneladas largas (t), 12 quintales (cwt) y 2 cuartos (qtr) por 47. Este ejemplo utiliza medidas avoirdupois : 1 t = 20 cwt, 1 cwt = 4 qtr.

 t cwt qtr 23 12 2 47 × ———————————————— 1. Multiplica todo por 47 1081 564 94 ———————————————— 2a. Llevar cuarto y sumar a cwt (94 = 23 × 4 + 2) (564) 94 23 2 ————— 587 2 2b. Lleva cwt y súmalo a t (587 = 29 × 20 + 7) (1081) 587 2 29 7 ———————————————— 3. Adición final 1110 7 2 ================= Respuesta: 1110 toneladas 7 cwt 2 cuartos

Se puede utilizar el mismo diseño y los mismos métodos para cualquier sistema de medidas tradicional y monedas no decimales, como el antiguo sistema británico de libras y peniques (£sd) .

Véase también

Referencias

  1. "Multiplicación" . www.mathematische-basteleien.de . Consultado el 15 de marzo de 2022 .
  2. Brent, Richard P (marzo de 1978). "Un paquete de aritmética de precisión múltiple para Fortran". ACM Transactions on Mathematical Software . 4 : 57–70 . CiteSeerX 10.1.1.117.8425 . doi : 10.1145/355769.355775 . S2CID 8875817 .  
  3. Eason, Gary (13 de febrero de 2000). "Regreso a clases para los padres" . BBC News .Eastaway, Rob (10 de septiembre de 2010). "Por qué los padres no saben hacer matemáticas hoy en día" . BBC News.
  4. Corlu, MS; Burlbaw, LM; Capraro, RM; Corlu, MA; Han, S. (2010). "La escuela del palacio otomano Enderun y el hombre de múltiples talentos, Matrakçı Nasuh" . Revista de la Sociedad Coreana de Educación Matemática Serie D: Investigación en Educación Matemática . 14 (1): 19– 31.
  5. Bogomolny, Alexander . "Multiplicación campesina" . www.cut-the-knot.org . Consultado el 4 de noviembre de 2017 .
  6. Wells, D. (1987). The Penguin Dictionary of Curious and Interesting Numbers . Penguin Books. pág. 44. ISBN  978-0-14-008029-2.
  7. McFarland, David (2007), Quarter Tables Revisited: Earlier Tables, Division of Labor in Table Construction, and Later Implementations in Analog Computers , p. 1 
  8. Robson, Eleanor (2008). Matemáticas en el antiguo Irak: una historia social . Princeton University Press. pág. 227. ISBN  978-0691201405.
  9. "Reseñas" , The Civil Engineer and Architect's Journal : 54–55 , 1857.
  10. Holmes, Neville (2003), "Multiplicación con cuartos de cuadrado", The Mathematical Gazette , 87 (509): 296– 299, doi : 10.1017/S0025557200172778 , JSTOR 3621048 , S2CID 125040256 .  
  11. Everett L., Johnson (marzo de 1980), "Un multiplicador digital de un cuarto de cuadrado", IEEE Transactions on Computers , vol. C-29, n.º 3, Washington, DC, EE. UU.: IEEE Computer Society, págs. 258–261 , doi : 10.1109/TC.1980.1675558 , ISSN 0018-9340 , S2CID 24813486     
  12. Putney, Charles (marzo de 1986). "La multiplicación más rápida del 6502 hasta la fecha" . Apple Assembly Line . 6 (6).
  13. "La ingeniosa forma en que las computadoras multiplican números grandes" . YouTube . 2 de enero de 2025.
  14. ^ Harvey , David ; van der Hoeven, Joris (2021). "Multiplicación de números enteros en el tiempoO(norteregistronorte){\displaystyle O(n\log n)}" (PDF) . Anales de Matemáticas . Segunda Serie. 193 (2): 563– 617. doi : 10.4007/annals.2021.193.2.4 . MR 4224716 . S2CID 109934776 .  
  15. Charles Babbage, Capítulo VIII – De la máquina analítica, números mayores tratados, Pasajes de la vida de un filósofo , Longman Green, Londres, 1864; página 125.
  16. D. Knuth, El arte de la programación informática , vol. 2, sec. 4.3.3 (1998)
  17. Schönhage, A.; Strassen, V. (1971). "Schnelle Multiplikation großer Zahlen" . Computación . 7 ( 3– 4): 281– 292. doi : 10.1007/BF02242355 . S2CID 9738629 . 
  18. Fürer, M. (2007). «Multiplicación de enteros más rápida» (PDF) . Actas del trigésimo noveno simposio anual de la ACM sobre teoría de la computación, 11-13 de junio de 2007, San Diego, California, EE. UU . pp. 57-66 . doi : 10.1145/1250790.1250800 . ISBN  978-1-59593-631-8. S2CID 8437794 . 
  19. De, A.; Saha, C.; Kurur, P.; Saptharishi, R. (2008). "Multiplicación rápida de enteros mediante aritmética modular". Actas del 40.º Simposio anual de la ACM sobre Teoría de la Computación (STOC) . págs. 499–506 . arXiv : 0801.1416 . doi : 10.1145/1374376.1374447 . ISBN  978-1-60558-047-0. S2CID 3264828 . 
  20. ^ Harvey, David; van der Hoeven, Joris; Lecerf, Grégoire (2016). "Multiplicación de enteros aún más rápida". Revista de Complejidad . 36 : 1– 30. arXiv : 1407.3360 . doi : 10.1016/j.jco.2016.03.001 . SEÑOR 3530637 . 
  21. Covanov, Svyatoslav; Thomé, Emmanuel (2019). "Multiplicación rápida de enteros usando primos de Fermat generalizados". Math. Comp. 88 (317): 1449– 1477. arXiv : 1502.02800 . doi : 10.1090/mcom/3367 . S2CID 67790860 . 
  22. Harvey, D.; van der Hoeven, J. (2019). "Multiplicación de enteros más rápida usando vectores reticulares cortos". The Open Book Series . 2 : 293–310 . arXiv : 1802.07932 . doi : 10.2140/obs.2019.2.293 . S2CID 3464567 . 
  23. Hartnett, Kevin (11 de abril de 2019). "Los matemáticos descubren la manera perfecta de multiplicar" . Quanta Magazine . Consultado el 3 de mayo de 2019 .
  24. Gilbert, Lachlan (04/04/2019). "Un genio de las matemáticas resuelve un problema de multiplicación de 48 años" . UNSW . Consultado el 18/04/2019 .
  25. Arora, Sanjeev; Barak, Boaz (2009). Complejidad computacional: un enfoque moderno . Cambridge University Press. ISBN 978-0-521-42426-4.
  26. Ablayev, F.; Karpinski, M. (2003). "Un límite inferior para la multiplicación de enteros en programas de ramificación de lectura única ordenados aleatorios" (PDF) . Information and Computation . 186 (1): 78– 89. doi : 10.1016/S0890-5401(03)00118-4 .
  27. Knuth, Donald E. (1988), El arte de la programación informática, volumen 2: algoritmos seminuméricos , Addison-Wesley , págs. 519, 706 
  28. Duhamel, P.; Vetterli, M. (1990). "Transformadas rápidas de Fourier: una revisión tutorial y un estado del arte" (PDF) . Procesamiento de señales . 19 (4): 259–299 Véase la Sección 4.1. Bibcode : 1990SigPr..19..259D . doi : 10.1016/0165-1684(90)90158-U .
  29. Johnson, SG; Frigo, M. (2007). "Una FFT de base dividida modificada con menos operaciones aritméticas" (PDF) . IEEE Trans. Signal Process . 55 (1): 111–9 Véase la Sección IV. Bibcode : 2007ITSP...55..111J . doi : 10.1109/TSP.2006.882087 . S2CID 14772428 . 
  30. von zur Gathen, Joaquín ; Gerhard, Jürgen (1999), Álgebra informática moderna , Cambridge University Press, págs. 243–244 , ISBN  978-0-521-64176-0.
  31. Castle, Frank (1900). Matemáticas de taller . Londres: MacMillan and Co. pág. 74 . 

Lecturas adicionales

  • Warren Jr., Henry S. (2013). Hacker's Delight (2.ª  ed.). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8.
  • Savard, John JG (2018) [2006]. "Técnicas aritméticas avanzadas" . quadibloc . Archivado del original el 3 de julio de 2018. Recuperado el 16 de julio de 2018 .
  • Johansson, Kenny (2008). Computaciones basadas en desplazamiento y suma de baja potencia y baja complejidad (PDF) (Tesis doctoral). Estudios de Linköping en Ciencia y Tecnología (1.ª  ed.). Linköping, Suecia: Departamento de Ingeniería Eléctrica, Universidad de Linköping . ISBN 978-91-7393-836-5ISSN 0345-7524 . N.° 1201. Archivado (PDF) del original el 13 de agosto de 2017. Consultado el 23 de agosto de 2021 . (x+268 páginas)

aritmética básica

  • Las diversas formas de utilizar la aritmética en las matemáticas cotidianas de UCSMP
  • Una presentación de PowerPoint sobre matemáticas antiguas
  • Vídeo Flash de multiplicación reticular

Algoritmos avanzados

  • Algoritmos de multiplicación utilizados por GMP