Escreva uma função ou programa nomeado que calcule o produto quaternion de dois quaternions. Use o mínimo de bytes possível.
Quaternions
Quaternions são uma extensão dos números reais que ampliam ainda mais os números complexos. Em vez de uma única unidade imaginária i
, os quaternions usam três unidades imaginárias i,j,k
que satisfazem os relacionamentos.
i*i = j*j = k*k = -1
i*j = k
j*i = -k
j*k = i
k*j = -i
k*i = j
i*k = -j
(Também há tabelas na página da Wikipedia .)
Em palavras, cada unidade imaginária se enquadra em -1
e o produto de duas unidades imaginárias diferentes é o terceiro restante, +/-
dependendo se a ordem cíclica (i,j,k)
é respeitada (isto é, a regra da mão direita ). Então, a ordem da multiplicação é importante.
Um quaternion geral é uma combinação linear de uma parte real e das três unidades imaginárias. Então, é descrito por quatro números reais (a,b,c,d)
.
x = a + b*i + c*j + d*k
Assim, podemos multiplicar dois quaternions usando a propriedade distributiva, tendo o cuidado de multiplicar as unidades na ordem correta e agrupando os termos no resultado.
(a + b*i + c*j + d*k) * (e + f*i + g*j + h*k)
= (a*e - b*f - c*g - d*h) +
(a*f + b*e + c*h - d*g)*i +
(a*g - b*h + c*e + d*f)*j +
(a*h + b*g - c*f + d*e)*k
Visto dessa maneira, a multiplicação de quaternion pode ser vista como um mapa de um par de quatro tuplas para uma única quatro, que é o que você deve implementar.
Formato
Você deve escrever um programa ou uma função nomeada . Um programa deve receber entradas do STDIN e imprimir o resultado. Uma função deve receber entradas de função e retornar (não imprimir) uma saída.
Os formatos de entrada e saída são flexíveis. A entrada é oito números reais (os coeficientes para dois quaternions) e a saída consiste em quatro números reais. A entrada pode ter oito números, duas listas de quatro números, uma matriz 2x4 etc. O formato de entrada / saída não precisa ser o mesmo. A ordem dos (1,i,j,k)
coeficientes depende de você.
Os coeficientes podem ser negativos ou não inteiros. Não se preocupe com precisão real ou transbordamentos.
Banido: Função ou tipos especificamente para quaterniões ou equivalentes.
Casos de teste
Estes estão no (1,i,j,k)
formato coeficiente.
[[12, 54, -2, 23], [1, 4, 6, -2]]
[-146, -32, 270, 331]
[[1, 4, 6, -2], [12, 54, -2, 23]]
[-146, 236, -130, -333]
[[3.5, 4.6, -0.24, 0], [2.1, -3, -4.3, -12]]
[20.118, 2.04, 39.646, -62.5]
Implementação de referência
No Python, como função:
#Input quaternions: [a,b,c,d], [e,f,g,h]
#Coeff order: [1,i,j,k]
def mult(a,b,c,d,e,f,g,h):
coeff_1 = a*e-b*f-c*g-d*h
coeff_i = a*f+b*e+c*h-d*g
coeff_j = a*g-b*h+c*e+d*f
coeff_k = a*h+b*g-c*f+d*e
result = [coeff_1, coeff_i, coeff_j, coeff_k]
return result
Python -
90 75 7269Pure Python, sem bibliotecas - 90:
Provavelmente é muito difícil diminuir essa solução "padrão" em Python. Mas estou muito curioso sobre o que os outros podem inventar. :)
Usando NumPy -
75 7269:Bem, como a entrada e a saída são bastante flexíveis, podemos usar algumas funções do NumPy e explorar a representação vetorial escalar :
Argumentos de entrada
s
et
são as partes escalares dos dois quaterniões (as partes reais) ep
eq
são as partes vetoriais correspondentes (as unidades imaginárias). Saída é uma lista que contém parte escalar e parte vetorial do quaternion resultante, sendo este último representado como matriz NumPy.Script de teste simples:
(
mult(...)
sendo a implementação de referência do OP.)Resultado:
fonte
Haskell, 85
Portá-lo para Haskell economiza alguns caracteres;)
fonte
Mathematica
8350Provavelmente pode ser jogado mais ..
Espaços e novas linhas não são contados e não são necessários.
Uso:
EDITAR Como isso funciona.
A função Mathematica
Permutations
faz todas as permutações possíveis de#2
(o segundo argumento). Há 24 permutações, mas precisamos apenas{e,f,g,h}
,{f,e,h,g}
,{g,h,e,f}
, e{h,g,f,e}
. Estas são as primeiras, 8ª, 17ª e 24ª permutações. Então o códigoexatamente as seleciona das permutações do segundo argumento e as retorna como uma matriz. Mas eles ainda não têm o sinal correto. O código
p[{-1,1,-1,1}][[1;;3]]
retorna uma matriz 3x4 com o sinal correto. Nós o anexamos{1,1,1,1}
usandoJoin
e fazendo uma multiplicação normal (Times
ou, como é o caso aqui, apenas escrevendo-as uma após a outra) entre duas matrizes para fazer uma multiplicação elemento por elemento no Mathematica.Então, finalmente, o resultado de
é a matriz
Fazer uma multiplicação de matrizes entre
{a,b,c,d}
(o primeiro argumento#1
) e a matriz anterior fornece o resultado desejado.EDIT 2 Código mais curto
Inspirado no código Python de Falko, divido o quaternion em uma parte escalar e vetorial, e uso o comando integrado do Mathematica
Cross
para calcular o produto cruzado das partes vetoriais:Uso:
fonte
1, 8, 17, 24
?Python, 94
A maneira mais direta não é muito longa.
fonte
JavaScript ES6 - 86
fonte
Lua - 99
Poderia muito bem.
"Unpack ()" de Lua libera os elementos de uma tabela. Portanto, a tabela 'arg' é onde todas as entradas da linha de comando são armazenadas (incluindo
arg[0]
qual é o nome do arquivo do programa, ela é descartada).fonte
Python,
5856 caracteresEu uso muito liberalmente a sala de manobra do formato de entrada / saída. As entradas são 4 números complexos, codificados da seguinte forma:
Ele gera um par de números complexos em um formato semelhante, o primeiro do par codifica o real e a
i
parte, o segundo codifica oj
ek
partes.Para ver isso funciona, observe que o primeiro quaternion é
x+y*j
e o segundo éz+w*j
. Apenas avalie(x+y*j)*(z+w*j)
e perceba quej*t
=conj(t)*j
para qualquer número imagináriot
.fonte
i
ej
agir como coeficientes complexos internos e externos. Que fascinante!(2*w.real-w)
.abs(w)**2/w
funcionaria mas por 0. Talvez até o exec com substituição de string valha a pena? `Sussurros v2 , 396 bytes
Experimente online!
Recebe entrada no formulário
e saídas como
A árvore de estrutura desta resposta é:
Uma boa parte dessa resposta vem de duas falhas principais no Whispers:
Portanto, podemos dividir o código em 3 seções.
Como funciona
Usaremos as seguintes definições para maior clareza e concisão:
A primeira seção é de longe a mais longa, estendendo-se da linha 1 à linha 22 :
Seção 2: Sinais e produtos
Seção 3: Partições e somas finais.
fonte