Quadratwurzel der Quaternion

11

Hintergrund

Quaternion ist ein Zahlensystem, das komplexe Zahlen erweitert. Ein Quaternion hat die folgende Form

a+bi+cj+dk

Dabei sind a,b,c,d reelle Zahlen und i,j,k drei grundlegende Quaternionseinheiten . Die Einheiten haben folgende Eigenschaften:

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

Beachten Sie, dass die Quaternion-Multiplikation nicht kommutativ ist .

Aufgabe

Berechnen Sie bei einer nicht reellen Quaternion mindestens eine ihrer Quadratwurzeln.

Wie?

Gemäß dieser Math.SE-Antwort können wir nicht-reale Quaternionen in der folgenden Form ausdrücken:

q=a+bu

wobei a,b reelle Zahlen sind und u der imaginäre Einheitsvektor in der Form xi+yj+zk mit x2+y2+z2=1 . Jedes solche u hat die Eigenschaft u2=1 , kann also als imaginäre Einheit betrachtet werden.

Dann sieht das Quadrat von q aus:

q2=(a2b2)+2abu

Umgekehrt können wir bei einem gegebenen Quaternion q=x+yu die Quadratwurzel von q durch Lösen der folgenden Gleichungen finden

x=a2b2,y=2ab

Dies ist identisch mit dem Finden der Quadratwurzel einer komplexen Zahl.

Beachten Sie, dass eine negative reelle Zahl unendlich viele Quadratwurzeln der Quaternion hat , eine nicht-reelle Quaternion jedoch nur zwei Quadratwurzeln .

Ein- und Ausgabe

Die Eingabe ist eine nicht-reale Quaternion. Sie können es als vier reelle (Gleitkomma-) Zahlen in einer beliebigen Reihenfolge und Struktur Ihrer Wahl annehmen. Nicht real bedeutet, dass mindestens eines von b,c,d nicht Null ist.

Die Ausgabe besteht aus einem oder zwei Quaternionen, die im Quadrat der Eingabe entsprechen.

Testfälle

   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

Mit diesem Python-Skript generiert . Für jeden Testfall ist nur eine der beiden richtigen Antworten angegeben. der andere ist alle vier Werte negiert.

Bewertungs & Gewinnkriterium

Es gelten die Standardregeln für . Das kürzeste Programm oder die kürzeste Funktion in Bytes in jeder Sprache gewinnt.

Bubbler
quelle
Können wir die Quaternion als nehmen a, (b, c, d)?
Nwellnhof
@nwellnhof Sicher. Sogar so etwas a,[b,[c,[d]]]ist in Ordnung, wenn man irgendwie Bytes damit sparen kann :)
Bubbler

Antworten:

29

APL (NARS) , 2 Byte

NARS bietet integrierte Unterstützung für Quaternionen. ¯ \ _ (⍨) _ / ¯

Adam
quelle
4
Ich kann nicht anders: Sie sollten "¯_ (ツ) _ / ¯" in Ihre Antwort aufnehmen
Barranka
7
Du hast diesen \
Andrew
@Barranka Fertig.
Adám
@ Andrew Schuld es auf der Android-App ... Vielen Dank für die Abholung :)
Barranka
2
Es wäre besser, wenn 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

Probieren Sie es online!

Mehr oder weniger eine rohe Formel. Ich dachte, ich könnte Listenverständnisse verwenden, um eine Schleife b,c,dzu erstellen, aber das scheint länger zu dauern. Python ist hier wirklich verletzt durch einen Mangel an Vektoroperationen, insbesondere Skalierung und Norm.

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]]

Probieren Sie es online!

Das direkte Lösen des Quadrats war auch kürzer als die Verwendung von Pythons Quadratwurzel mit komplexen Zahlen, um es wie in der Problemstellung zu lösen.

xnor
quelle
"Die Eingabe ist eine nicht-reelle Quaternion. Sie können sie als vier reelle Zahlen (Gleitkommazahlen) in einer beliebigen Reihenfolge und Struktur Ihrer Wahl annehmen." Sie können also davon ausgehen, dass es sich um eine Pandas-Serie oder ein Numpy-Array handelt. Reihen haben Skalierung mit einfacher Multiplikation, und es gibt verschiedene Möglichkeiten, Norm zu erhalten, wie z (s*s).sum()**.5.
Akkumulation
6

Wolfram Language (Mathematica) , 19 Bytes

Sqrt
<<Quaternions`

Probieren Sie es online!

In Mathematica ist Quaternion ebenfalls integriert, es ist jedoch ausführlicher.


Obwohl eingebaute Funktionen cool aussehen, sollten Sie Lösungen wählen, die keine eingebauten Funktionen verwenden! Ich möchte nicht, dass die Abstimmungen bei Fragen, die das HNQ erreichen, schief laufen.

user202729
quelle
4

JavaScript (ES7), 55 53 Bytes

Basierend auf der direkten Formel von xnor .

Übernimmt die Eingabe als Array.

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

Probieren Sie es online!

Wie?

Gegeben ein Array q=[ein,b,c,d]Dies berechnet:

x=ein+ein2+b2+c2+d22

Und kehrt zurück:

[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
quelle
3

Haskell , 51 Bytes

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

Probieren Sie es online!

Eine direkte Formel. Der Haupttrick, um den Realteil der Ausgabe so r/sqrt(r*2)auszudrücken, dass er dem Imaginärteil-Ausdruck entspricht, wodurch ein paar Bytes eingespart werden:

54 Bytes

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

Probieren Sie es online!

xnor
quelle
3

Holzkohle , 32 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Port von @ xnors Python-Antwort. Erläuterung:

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

Quadrieren Sie alle Elemente der Eingabe und nehmen Sie die Summe und dann die Quadratwurzel. Dies berechnet|x+yu|=x2+y2=(ein2-b2)2+(2einb)2=ein2+b2. Hinzufügenx gibt 2ein2 das wird dann verdoppelt und Quadratwurzel zu geben 2ein.

≧∕ηθ

weil y=2einb, Berechnung b durch dividieren durch 2ein.

§≔θ⁰⊘η

Setzen Sie das erste Element des Arrays (dh den Realteil) auf die Hälfte von 2ein.

Iθ

Wandeln Sie die Werte in Zeichenfolgen um und geben Sie sie implizit aus.

Neil
quelle
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

Port von @xnors Python 2 Antwort .

Probieren Sie es online aus.

Erläuterung:

(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
quelle
2

05AB1E , 14 Bytes

nOtsн+·t©/¦®;š

Port von @xnors Python 2 Antwort .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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
quelle
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)

Port meiner Java 8-Antwort , gibt jedoch ein Tupel anstelle eines Strings zurück. Ich dachte, das wäre kürzer gewesen, aber leider ist Math.Sqrtein System-import in C # .NET erforderlich , der 4 Bytes länger als 10 Bytes kürzer ist ..>.>

Die Lambda-Deklaration sieht allerdings ziemlich lustig aus:

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

Probieren Sie es online aus.

Kevin Cruijssen
quelle
1

Perl 6 , 49 Bytes

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

Probieren Sie es online!

Eingegebene Curry-Funktion als f(b,c,d)(a). Gibt quaternion als zurücka,(b,c,d) .

Erläuterung

{;                                             }  # 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
quelle