Saltar al contenido

Multiplicar cuaterniones

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 py 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 1está 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ó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *