Raiz quadrada de Quaternion

11

fundo

Quaternion é um sistema numérico que estende números complexos. Um quaternion tem a seguinte forma

a+bi+cj+dk

onde a,b,c,d são números reais e i,j,k são três unidades fundamentais de quaternião . As unidades possuem as seguintes propriedades:

i2=j2=k2=1
ij=k,jk=i,ki=j
ji=k,kj=i,ik=j

Observe que a multiplicação de quaternion não é comutativa .

Tarefa

Dado um quaternion não real , calcule pelo menos uma de suas raízes quadradas.

Quão?

De acordo com esta resposta Math.SE , podemos expressar qualquer quaternion não real da seguinte forma:

q=a+bu

onde a,b são números reais e u é o vetor da unidade imaginária na forma xi+yj+zk com x2+y2+z2=1 . Qualquer um desses u possui a propriedade u2=1 , para que possa ser visto como a unidade imaginária.

Então o quadrado de q fica assim:

q2=(a2b2)+2abu

Inversamente, dado um quaternário q=x+yu , podemos encontrar a raiz quadrada de q resolvendo as seguintes equações

x=a2b2,y=2ab

que é idêntico ao processo de encontrar a raiz quadrada de um número complexo.

Observe que um número real negativo tem infinitas raízes quadradas em quaterniões, mas um quaternion não real possui apenas duas raízes quadradas .

Entrada e saída

Input é um quaternion não real. Você pode assumir isso como quatro números reais (ponto flutuante), em qualquer ordem e estrutura de sua escolha. Não real significa que pelo menos um de b,c,d é diferente de zero.

A saída é um ou dois quaternions que, ao quadrado, são iguais à entrada.

Casos de teste

   Input (a, b, c, d)  =>  Output (a, b, c, d) rounded to 6 digits

 0.0,  1.0,  0.0,  0.0 =>  0.707107,  0.707107,  0.000000,  0.000000
 1.0,  1.0,  0.0,  0.0 =>  1.098684,  0.455090,  0.000000,  0.000000
 1.0, -1.0,  1.0,  0.0 =>  1.168771, -0.427800,  0.427800,  0.000000
 2.0,  0.0, -2.0, -1.0 =>  1.581139,  0.000000, -0.632456, -0.316228
 1.0,  1.0,  1.0,  1.0 =>  1.224745,  0.408248,  0.408248,  0.408248
 0.1,  0.2,  0.3,  0.4 =>  0.569088,  0.175720,  0.263580,  0.351439
99.0,  0.0,  0.0,  0.1 =>  9.949876,  0.000000,  0.000000,  0.005025

Gerado usando este script Python . Somente uma das duas respostas corretas é especificada para cada caso de teste; o outro são todos os quatro valores negados.

Critério de pontuação e vitória

Aplicam-se as regras de padrão . O programa ou função mais curto em bytes em cada idioma vence.

Bubbler
fonte
Podemos tomar o quaternion como a, (b, c, d)?
Nwellnhof #
@nwellnhof Com certeza. Mesmo algo como a,[b,[c,[d]]]é bom, se você pode de alguma forma salvar bytes com ele :)
Bubbler

Respostas:

29

APL (NARS) , 2 bytes

O NARS tem suporte interno para quaternions. ¯ \ _ (⍨) _ / ¯

Adão
fonte
4
Não posso evitar: você deve incluir "¯_ (ツ) _ / ¯" Em sua resposta
Barranka
7
Você largou este \
Andrew
@Barranka Done.
Adám 16/11/18
@ Andrew culpar o aplicativo Android ... Obrigado por pegá-la :)
Barranka
2
Seria melhor se ele é¯\_(⍨)√¯
Zachary
8

Python 2 , 72 bytes

def f(a,b,c,d):s=((a+(a*a+b*b+c*c+d*d)**.5)*2)**.5;print s/2,b/s,c/s,d/s

Experimente online!

Mais ou menos uma fórmula crua. Eu pensei que poderia usar a compreensão da lista para fazer um loop b,c,d, mas isso parece ser mais longo. O Python é realmente prejudicado aqui pela falta de operações vetoriais, em especial por escala e norma.

Python 3 , 77 bytes

def f(a,*l):r=a+sum(x*x for x in[a,*l])**.5;return[x/(r*2)**.5for x in[r,*l]]

Experimente online!

Resolver a quadrática diretamente também foi mais curto do que usar a raiz quadrada de número complexo do Python para resolvê-la como na declaração do problema.

xnor
fonte
"A entrada é um quaternion não real. Você pode aceitá-lo como quatro números reais (ponto flutuante), em qualquer ordem e estrutura de sua escolha." Portanto, você pode considerar uma série de pandas ou uma matriz numpy. As séries têm escalonamento com multiplicação simples e existem várias maneiras de obter normas, como (s*s).sum()**.5.
Acccumulation
6

Wolfram Language (Mathematica) , 19 bytes

Sqrt
<<Quaternions`

Experimente online!

O Mathematica também possui o Quaternion, mas é mais detalhado.


Embora os built-ins pareçam legais, faça soluções upvote que também não usam os built-ins! Não quero que votos nas perguntas que chegam ao HNQ sejam distorcidos.

user202729
fonte
4

JavaScript (ES7), 55 53 bytes

Com base na fórmula direta usada pelo xnor .

Recebe entrada como uma matriz.

q=>q.map(v=>1/q?v/2/q:q=((v+Math.hypot(...q))/2)**.5)

Experimente online!

Quão?

q=[a,b,c,d]

x=a+a2+b2+c2+d22

E retorna:

[x,b2x,c2x,d2x]

q =>                            // q[] = input array
  q.map(v =>                    // for each value v in q[]:
    1 / q ?                     //   if q is numeric (2nd to 4th iteration):
      v / 2 / q                 //     yield v / 2q
    :                           //   else (1st iteration, with v = a):
      q = (                     //     compute x (as defined above) and store it in q
        (v + Math.hypot(...q))  //     we use Math.hypot(...q) to compute:
        / 2                     //       (q[0]**2 + q[1]**2 + q[2]**2 + q[3]**2) ** 0.5
      ) ** .5                   //     yield x
  )                             // end of map()
Arnauld
fonte
3

Haskell , 51 bytes

f(a:l)|r<-a+sqrt(sum$(^2)<$>a:l)=(/sqrt(r*2))<$>r:l

Experimente online!

Uma fórmula direta. O principal truque para expressar a parte real da saída como r/sqrt(r*2)paralelo à expressão da parte imaginária, que economiza alguns bytes em:

54 bytes

f(a:l)|s<-sqrt$2*(a+sqrt(sum$(^2)<$>a:l))=s/2:map(/s)l

Experimente online!

xnor
fonte
3

Carvão , 32 bytes

≔X⊗⁺§θ⁰XΣEθ×ιι·⁵¦·⁵η≧∕ηθ§≔θ⁰⊘ηIθ

Experimente online! Link é a versão detalhada do código. Porta da resposta Python do @ xnor. Explicação:

≔X⊗⁺§θ⁰XΣEθ×ιι·⁵¦·⁵η

|x+yu|=x2+y2=(a2b2)2+(2ab)2=a2+b2x2a22a

≧∕ηθ

y=2abb2a

§≔θ⁰⊘η

2a

Iθ

Transmitir os valores para string e imprimir implicitamente.

Neil
fonte
3

Java 8, 84 bytes

(a,b,c,d)->(a=Math.sqrt(2*(a+Math.sqrt(a*a+b*b+c*c+d*d))))/2+" "+b/a+" "+c/a+" "+d/a

Porta da resposta Python 2 do @xnor .

Experimente online.

Explicação:

(a,b,c,d)->           // Method with four double parameters and String return-type
  (a=                 //  Change `a` to:
     Math.sqrt(       //   The square root of:
       2*             //    Two times:
         (a+          //     `a` plus,
          Math.sqrt(  //     the square-root of:
            a*a       //      `a`  squared,
            +b*b      //      `b` squared,
            +c*c      //      `c` squared,
            +d*d))))  //      And `d` squared summed together
  /2                  //  Then return this modified `a` divided by 2
  +" "+b/a            //  `b` divided by the modified `a`
  +" "+c/a            //  `c` divided by the modified `a`
  +" "+d/a            //  And `d` divided by the modified `a`, with space delimiters
Kevin Cruijssen
fonte
2

05AB1E , 14 bytes

nOtsн+·t©/¦®;š

Porta da resposta Python 2 do @xnor .

Experimente online ou verifique todos os casos de teste .

Explicação:

n                 # Square each number in the (implicit) input-list
 O                # Sum them
  t               # Take the square-root of that
   sн+            # Add the first item of the input-list
      ·           # Double it
       t          # Take the square-root of it
        ©         # Store it in the register (without popping)
         /        # Divide each value in the (implicit) input with it
          ¦       # Remove the first item
           ®;     # Push the value from the register again, and halve it
             š    # Prepend it to the list (and output implicitly)
Kevin Cruijssen
fonte
2

C # .NET, 88 bytes

(a,b,c,d)=>((a=System.Math.Sqrt(2*(a+System.Math.Sqrt(a*a+b*b+c*c+d*d))))/2,b/a,c/a,d/a)

Porta da minha resposta Java 8 , mas retorna uma Tupla em vez de uma String. Eu pensei que teria sido mais curto, mas, infelizmente, Math.Sqrtexigem uma Systemimportação em C # .NET, terminando em 4 bytes a mais em vez de 10 bytes a menos ..>.>

A declaração lambda parece bem engraçada, no entanto:

System.Func<double, double, double, double, (double, double, double, double)> f =

Experimente online.

Kevin Cruijssen
fonte
1

Perl 6 , 49 bytes

{;(*+@^b>>².sum**.5*i).sqrt.&{.re,(@b X/2*.re)}}

Experimente online!

Função ao curry tendo entrada como f(b,c,d)(a). Retorna quaternion como a,(b,c,d).

Explicação

{;                                             }  # Block returning WhateverCode
     @^b>>².sum**.5     # Compute B of quaternion written as q = a + B*u
                        # (length of vector (b,c,d))
  (*+              *i)  # Complex number a + B*i
                      .sqrt  # Square root of complex number
                           .&{                }  # Return
                              .re,  # Real part of square root
                                  (@b X/2*.re)  # b,c,d divided by 2* real part
Nwellnhof
fonte