Kuaterniyon karekökü


11

Arka fon

Kuaterniyon karmaşık sayıları genişleten bir sayı sistemidir. Bir kuaterniyon aşağıdaki forma sahiptir

a+bi+cj+dk

burada a,b,c,d gerçek sayılar ve i,j,k üç temel kuaterniyon birimidir . Birimler aşağıdaki özelliklere sahiptir:

i2=j2=k2=1
ij=k,jk=i,ki=j
jben=-k,kj=-ben,benk=-j

Kuaterniyon çarpımının değişmeli olmadığını unutmayın .

Görev

Gerçek olmayan bir kuaterniyon verildiğinde , kareköklerinden en az birini hesaplayın.

Nasıl?

Göre bu Math.SE cevap , aşağıdaki formda olmayan gerçek quaternion ifade edebilir:

q=bir+bu

burada bir,b reel sayılardır ve u olduğu şeklinde hayali birim vektör xben+yj+zk ile x2+y2+z2=1 . Bu tür u özelliğine sahiptir u2=-1 hayali birim olarak görülebilir, böylece.

Sonra q karesi şöyle görünür:

q2=(bir2-b2)+2birbu

Tersine, bir kuaterniyon q'=x+yu verildiğinde , aşağıdaki denklemleri çözerek q' un kare kökünü bulabiliriz

x=bir2-b2,y=2birb

bu karmaşık bir sayının kare kökünü bulma işlemiyle aynıdır.

Negatif bir gerçek sayının sonsuz sayıda kuaterniyon karekökü olduğunu, ancak gerçek olmayan bir kuaterniyonun sadece iki kare kökü olduğunu unutmayın .

Giriş ve çıkış

Girdi gerçek olmayan bir kuaterniyondur. Seçtiğiniz herhangi bir sırada ve yapıda dört gerçek (kayan nokta) sayı olarak alabilirsiniz. Gerçek olmayan , b,c,d en az birinin sıfır olmadığı anlamına gelir .

Çıktı, kare olduğunda girdiye eşit olan bir veya iki kuaterniyondur.

Test senaryoları

   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

Bu Python betiği kullanılarak oluşturulur . Her test durumu için iki doğru cevaptan sadece biri belirtilmiştir; diğeri ise dört değerin de olumsuzlanmasıdır.

Puanlama ve kazanma kriteri

Standart kuralları geçerlidir. Her dilde bayt cinsinden en kısa program veya işlev kazanır.


Kuaterniyonu şu şekilde alabilir miyiz a, (b, c, d)?
nwellnhof

@nwellnhof Elbette. Hatta bir şey a,[b,[c,[d]]]onunla bayt kaydedebilirsiniz eğer, gayet iyi, :)
Bubbler

Yanıtlar:



8

Python 2,72 bayt

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

Çevrimiçi deneyin!

Aşağı yukarı ham formül. Liste kavrayışlarını kullanabilmek için kullanabileceğimi düşündüm b,c,d, ancak bu daha uzun görünüyor. Python, özellikle ölçekleme ve norm gibi vektör işlemlerinin olmaması nedeniyle gerçekten zarar görüyor.

Python 3 , 77 bayt

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

Çevrimiçi deneyin!

Karesel olanı doğrudan çözmek, Python'un karmaşık sayı karekökünü problem ifadesinde olduğu gibi çözmek için de kullanmaktan daha kısaydı.


"Girdi gerçek olmayan bir kuaterniyondur. Seçtiğiniz herhangi bir sırada ve yapıda dört gerçek (kayan nokta) sayı olarak alabilirsiniz." Yani bir panda serisi veya numpy dizisi olarak düşünebilirsiniz. Seriler basit çarpma ile ölçeklendirmeye sahiptir ve norm almanın çeşitli yolları vardır (s*s).sum()**.5.
Birikim


4

JavaScript (ES7), 55 53 bayt

Xnor tarafından kullanılan doğrudan formüle dayanmaktadır .

Girişi dizi olarak alır.

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

Çevrimiçi deneyin!

Nasıl?

q=[bir,b,c,d]

x=bir+bir2+b2+c2+d22

Ve döndürür:

[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 bayt

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

Çevrimiçi deneyin!

Doğrudan formül. Çıktının gerçek kısmını, r/sqrt(r*2)birkaç bayt tasarruf eden hayali parça ifadesine paralel olarak ifade etmenin ana hilesi :

54 bayt

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

Çevrimiçi deneyin!


3

Kömür , 32 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. @ Xnor'ın Python cevabının limanı. Açıklama:

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

|x+yu|=x2+y2=(bir2-b2)2+(2birb)2=bir2+b2x2bir22bir

≧∕ηθ

y=2birbb2bir

§≔θ⁰⊘η

2bir

Iθ

Değerleri dizeye yayınlar ve dolaylı olarak yazdırır.


3

Java 8, 84 bayt

(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 @xnor 'Python 2 cevap s .

Çevrimiçi deneyin.

Açıklama:

(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 bayt

nOtsн+·t©/¦®;š

Port @xnor 'Python 2 cevap s .

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

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 bayt

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

Bağlantı noktasıma Java 8 yanıt veriyor, ancak String yerine bir Tuple döndürüyor. Bunu kısa olurdu, ama ne yazık ki Math.Sqrtbir ihtiyaçSystem C # .NET -import , 10 bayt daha kısa yerine 4 bayt daha uzun biten ..>.

Lambda bildirisi oldukça komik görünüyor:

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

Çevrimiçi deneyin.


1

Perl 6 , 49 bayt

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

Çevrimiçi deneyin!

Curried işlevi giriş olarak alır f(b,c,d)(a). Kuaterniyonu şu şekilde döndürür:a,(b,c,d) .

açıklama

{;                                             }  # 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.