Este grupo de especialistas pasados ciertos días de investigación y de recopilar de información, encontramos los datos necesarios, esperamos que te sea útil en tu proyecto.
Solución:
pitón (83)
r=lambda A,B,R=range(4):[sum(A[m]*B[m^p]*(-1)**(14672>>p+4*m)for m in R)for p in R]
Toma dos listas A,B
en [1,i,j,k]
orden y devuelve un resultado en el mismo formato.
Él key la idea es que con [1,i,j,k]
correspondiente a índices [0,1,2,3]
, obtienes el índice del producto (hasta el signo) haciendo XOR en los índices. Entonces, los términos que se colocan en el índice p
son los que indexan XOR a p
y son por tanto los productos A[m]*B[m^p]
.
Solo queda hacer que las señales funcionen. La forma más corta que encontré fue simplemente codificarlos en una magia string. Las 16 posibilidades de (m,p)
se convierten en numeros 0
para 15
como p+4*m
. El número 14672
en binario tiene 1
está en los lugares donde -1
se necesitan señales. Desplazándolo el número apropiado de lugares, un 1
o 0
termina en el último dígito, haciendo que el número sea par o impar, y así (-1)**
es cualquiera 1
o -1
según sea necesario.
CJam, 4945 39 bytes
"cM-^M-^G-^^KM-zP"256bGbq~m*f=:*4/:-W*/W*]`
Lo anterior usa notación de intercalación y M, ya que el código contiene caracteres no imprimibles.
A costa de dos bytes adicionales, esos caracteres se pueden evitar:
6Z9C8 7YDXE4BFA5U]q~m*f=:*4/:-W*/W*]`
Puedes probar esta versión en línea: CJam interpreter
Casos de prueba
Calcular (a + bi + cj + dk) * (e + fi + gj + hk)
use la siguiente entrada:
[ d c b a ] [ h g f e ]
La salida será
[ z y x w ]
que corresponde al cuaternión w + xi + yj + zk
.
$ base64 -d > product.cjam <<< ImOchy0eS/pQIjI1NmJHYnF+bSpmez06Kn00L3s6LVcqfS9XKl1g
$ wc -c product.cjam
39 product.cjam
$ LANG=en_US cjam product.cjam <<< "[23 -2 54 12] [-2 6 4 1]"; echo
[331 270 -32 -146]
$ LANG=en_US cjam product.cjam <<< "[-2 6 4 1] [23 -2 54 12]"; echo
[-333 -130 236 -146]
$ LANG=en_US cjam product.cjam <<< "[0 -0.24 4.6 3.5] [-12 -4.3 -3 2.1]"; echo
[-62.5 39.646 2.04 20.118]
Cómo funciona
6Z9C8 7YDXE4BFA5U] " Push the array [ 6 3 9 12 8 7 2 13 1 14 4 11 15 10 5 0]. ";
q~ " Read from STDIN and interpret the input. ";
m* " Compute the cartesian product of the input arrays. ";
f " Execute the following for each element of the first array: ";
" Push the cartesian product (implicit). ";
= " Retrieve the corresponding pair of coefficients. ";
:* " Calculate their product. ";
" ";
4/ " Split into chunks of 4 elements. ";
:-W*/ " For each, subtract the first element from the sum of the others. ";
W* " Multiply the last integers (coefficient of 1) by -1. ";
]` " Collect the results into an array and stringify it. ";
Pitón - 90 75 72 69
Python puro, sin bibliotecas - 90:
m=lambda a,b,c,d,e,f,g,h:[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]
Probablemente sea bastante difícil acortar esta solución "predeterminada" en Python. Pero tengo mucha curiosidad en cuanto a lo que otros podrían hacer. 🙂
Usando NumPy - 75 72 69:
Bueno, dado que la entrada y la salida son bastante flexibles, podemos usar algunas funciones NumPy y explotar la representación escalar-vectorial:
import numpy
m=lambda s,p,t,q:[s*t-sum(p*q),s*q+t*p+numpy.cross(p,q)]
Argumentos de entrada s
y t
son las partes escalares de los dos cuaterniones (las partes reales) y p
y q
son las partes correspondientes del vector (las unidades imaginarias). La salida es una lista que contiene la parte escalar y la parte vectorial del cuaternión resultante, esta última representada como NumPy array.
Guión de prueba simple:
for i in range(5):
a,b,c,d,e,f,g,h=np.random.randn(8)
s,p,t,q=a, np.array([b, c, d]), e, np.array([f, g, h])
print mult(a, b, c, d, e, f, g, h), "n", m(s,p,t,q)
(mult(...)
siendo la implementación de referencia del OP).
Producción:
[1.1564241702553644, 0.51859264077125156, 2.5839001110572792, 1.2010364098925583]
[1.1564241702553644, array([ 0.51859264, 2.58390011, 1.20103641])]
[-1.8892934508324888, 1.5690229769129256, 3.5520713781125863, 1.455726589916204]
[-1.889293450832489, array([ 1.56902298, 3.55207138, 1.45572659])]
[-0.72875976923685226, -0.69631848934167684, 0.77897519489219036, 1.4024428845608419]
[-0.72875976923685226, array([-0.69631849, 0.77897519, 1.40244288])]
[-0.83690812141836401, -6.5476014589535243, 0.29693969165495304, 1.7810682337361325]
[-0.8369081214183639, array([-6.54760146, 0.29693969, 1.78106823])]
[-1.1284033842268242, 1.4038096725834259, -0.12599103441714574, -0.5233468317643214]
[-1.1284033842268244, array([ 1.40380967, -0.12599103, -0.52334683])]
Tienes la posibilidad recomendar este tutorial si te ayudó.