Raíz cuadrada de cuaternión


11

Antecedentes

Quaternion es un sistema de números que extiende números complejos. Un cuaternión tiene la siguiente forma

a+bi+cj+dk

donde a,b,c,d son números reales e i,j,k son tres unidades fundamentales de cuaternión . Las unidades tienen las siguientes propiedades:

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

Tenga en cuenta que la multiplicación de cuaterniones no es conmutativa .

Tarea

Dado un cuaternión no real , calcule al menos una de sus raíces cuadradas.

¿Cómo?

De acuerdo con esta respuesta de Math.SE , podemos expresar cualquier cuaternión no real de la siguiente forma:

q=a+bu

donde a,b son números reales y u es el vector unitario imaginario en la forma xi+yj+zk con x2+y2+z2=1 . Cualquiera de estas u tiene la propiedad u2=1 , por lo que puede verse como la unidad imaginaria.

Entonces el cuadrado de q ve así:

q2=(a2b2)+2abu

Inversamente, dado un cuaternión q=x+yu , podemos encontrar la raíz cuadrada de q resolviendo las siguientes ecuaciones

x=a2b2,y=2ab

que es idéntico al proceso de encontrar la raíz cuadrada de un número complejo.

Tenga en cuenta que un número real negativo tiene infinitas raíces cuadradas de cuaterniones, pero un cuaternión no real tiene solo dos raíces cuadradas .

Entrada y salida

La entrada es un cuaternión no real. Puede tomarlo como cuatro números reales (punto flotante), en cualquier orden y estructura de su elección. No real significa que al menos uno de b,c,d es distinto de cero.

La salida es uno o dos cuaterniones que, al cuadrado, son iguales a la entrada.

Casos de prueba

   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

Generado usando este script de Python . Solo se especifica una de las dos respuestas correctas para cada caso de prueba; el otro es los cuatro valores negados.

Criterio de puntuación y ganador

Se aplican reglas estándar de . El programa o función más corto en bytes en cada idioma gana.


¿Podemos tomar el cuaternión como a, (b, c, d)?
nwellnhof

@nwellnhof Claro. Incluso algo así a,[b,[c,[d]]]está bien, si de alguna manera puedes guardar bytes con él :)
Bubbler

Respuestas:


29

APL (NARS) , 2 bytes

NARS tiene soporte incorporado para cuaterniones. ¯ \ _ (⍨) _ / ¯


44
No puedo evitarlo: debes incluir "¯_ (ツ) _ / ¯" en tu respuesta
Barranka

77
Usted dejó caer este \
Andrew

@Barranka Hecho.
Adám

@Andrew le echa la culpa a la aplicación de Android ... Gracias por recogerlo :)
Barranka

2
Sería mejor si es¯\_(⍨)√¯
Zacharý

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

Pruébalo en línea!

Más o menos una fórmula cruda. Pensé que podría usar las comprensiones de listas para repetir b,c,d, pero esto parece ser más largo. Python se ve realmente afectado aquí por la falta de operaciones vectoriales, en particular el escalado y la 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]]

Pruébalo en línea!

Resolver el cuadrático directamente también fue más corto que usar la raíz cuadrada de números complejos de Python para resolverlo como en el enunciado del problema.


"La entrada es un cuaternión no real. Puede tomarlo como cuatro números reales (punto flotante), en cualquier orden y estructura de su elección". Por lo tanto, puede considerar que se trata de una serie de pandas o una matriz numpy. Las series tienen escala con multiplicación simple, y hay varias formas de obtener la norma, como (s*s).sum()**.5.
Acumulación

6

Wolfram Language (Mathematica) , 19 bytes

Sqrt
<<Quaternions`

Pruébalo en línea!

Mathematica también tiene Quaternion incorporado, pero es más detallado.


Si bien los complementos se ven geniales, ¡vota soluciones que no utilicen los complementos también! No quiero que los votos sobre las preguntas que lleguen a HNQ estén sesgados.


4

JavaScript (ES7), 55 53 bytes

Basado en la fórmula directa utilizada por xnor .

Toma la entrada como una matriz.

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

Pruébalo en línea!

¿Cómo?

q=[a,b,c,d]

x=a+a2+b2+c2+d22

Y vuelve:

[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()

3

Haskell , 51 bytes

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

Pruébalo en línea!

Una fórmula directa. El truco principal para expresar la parte real de la salida r/sqrt(r*2)en paralelo a la expresión de la parte imaginaria, que ahorra unos pocos bytes sobre:

54 bytes

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

Pruébalo en línea!


3

Carbón , 32 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Puerto de la respuesta Python de @ xnor. Explicación:

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

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

≧∕ηθ

y=2abb2a

§≔θ⁰⊘η

2a

Iθ

Convierta los valores en una cadena e imprima implícitamente.


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

Puerto de la respuesta Python 2 de @xnor .

Pruébalo en línea.

Explicación:

(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

2

05AB1E , 14 bytes

nOtsн+·t©/¦®;š

Puerto de la respuesta Python 2 de @xnor .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

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)


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)

El puerto de mi respuesta Java 8 , pero devuelve una Tupla en lugar de una Cadena. Pensé que habría sido más corto, pero desafortunadamente Math.Sqrtrequieren una Systemimportación en C # .NET, que termina en 4 bytes más en lugar de 10 bytes más cortos ..>.>

Sin embargo, la declaración lambda parece bastante divertida:

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

Pruébalo en línea.


1

Perl 6 , 49 bytes

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

Pruébalo en línea!

Función curry tomando entrada como f(b,c,d)(a). Devuelve quaternion como a,(b,c,d).

Explicación

{;                                             }  # 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.