Кватерніон квадратний корінь


11

Фон

Кватерніон - система числення, яка розширює складні числа. Кватерніон має таку форму

а+бi+cj+гк

де а,б,c,г - дійсні числа, а i,j,к - три основні кватерніонні одиниці . Агрегати мають такі властивості:

i2=j2=к2=-1
ij=к,jк=i,кi=j
ji=-к,кj=-i,iк=-j

Зауважимо, що множення кватерніона не є комутативним .

Завдання

Враховуючи нереальний кватерніон, обчисліть хоча б одне його квадратне коріння.

Як?

Відповідно до цієї відповіді Math.SE , ми можемо висловити будь-який нереальний кватерніон у такій формі:

q=а+бу

де а,б - дійсні числа і у - уявний одиничний вектор у вигляді хi+уj+zк з х2+у2+z2=1 . Будь-який такий у має властивість у2=-1 , тому його можна розглядати як уявну одиницю.

Тоді квадрат q виглядає так:

q2=(а2-б2)+2абу

І навпаки, задавши кватерніон q'=х+уу , ми можемо знайти квадратний корінь q' , розв’язавши наступні рівняння

х=а2-б2,у=2аб

що тотожне процесу знаходження квадратного кореня складного числа.

Зауважте, що від'ємне дійсне число має нескінченно багато квадратних коренів кватерніона, але нереальне кватерніон має лише два квадратних кореня .

Вхід і вихід

Введення - нереальний кватерніон. Ви можете прийняти його як чотири реальних числа (з плаваючою комою) у будь-якому порядку та структурі на ваш вибір. Нереальне означає, що принаймні один з б,c,г не дорівнює нулю.

Вихід - це один або два кватерніона, які при квадраті дорівнюють вводу.

Тестові справи

   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

Створено за допомогою цього сценарію Python . Для кожного тестового випадку вказується лише одна з двох правильних відповідей; інше - усі чотири значення заперечуються.

Критерій оцінювання та виграшу

Діють стандартні правила . Виграє найкоротша програма або функція в байтах на кожній мові.


Чи можемо ми прийняти кватерніон як a, (b, c, d)?
nwellnhof

@nwellnhof Звичайно. Навіть щось на кшталт a,[b,[c,[d]]]чудово, якщо ви зможете якось зберегти байти за допомогою нього :)
Bubbler

Відповіді:


29

APL (NARS) , 2 байти

NARS має вбудовану підтримку кватерніонів. ¯ \ _ (⍨) _ / ¯


4
Я не можу допомогти: у своїй відповіді слід включити "¯_ (ツ) _ / ¯"
Barranka

7
Ви кинули це \
Андрій

@Barranka Готово.
Адам

@Andrew звинувачує це в додатку для Android ... Дякую, що його
забрали

2
Було б краще, якщо це¯\_(⍨)√¯
Zacharý

8

Python 2 , 72 байти

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

Спробуйте в Інтернеті!

Більш-менш сира формула. Я думав, що можу використати розуміння списку, щоб перейти на цикл b,c,d, але це, здається, довше. Python тут дійсно болить через відсутність векторних операцій, зокрема масштабування та норми.

Python 3 , 77 байт

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

Спробуйте в Інтернеті!

Розв’язання прямокутного квадрата також було коротшим, ніж використання кореня квадратного числа комплексного числа Python для його вирішення, як у постановці проблеми.


"Введення - це нереальний кватерніон. Ви можете вважати його чотирма реальними числами (з плаваючою комою) у будь-якому порядку та структурі на ваш вибір." Таким чином, ви можете вважати, що це серія панди чи нумерований масив. Серії мають масштабування за допомогою простого множення, і існують різні способи отримати норму, наприклад (s*s).sum()**.5.
Накопичення

6

Мова Вольфрама (Mathematica) , 19 байт

Sqrt
<<Quaternions`

Спробуйте в Інтернеті!

У Mathematica також є вбудований Кватерніон, але він більш багатослівний.


Хоча вбудовані файли виглядають круто, вживати рішення, які не використовують також вбудовані модулі! Я не хочу, щоб голоси на питання, що надходять до HNQ, були скасовані.


4

JavaScript (ES7), 55 53 байти

На основі прямої формули використовуваної xnor .

Приймає дані як масив.

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

Спробуйте в Інтернеті!

Як?

q=[а,б,c,г]

х=а+а2+б2+c2+г22

І повертає:

[х,б2х,c2х,г2х]

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 байт

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

Спробуйте в Інтернеті!

Пряма формула. Основна хитрість висловити реальну частину виводу як r/sqrt(r*2)паралельну уявній частині виразу, що економить кілька байтів на:

54 байти

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

Спробуйте в Інтернеті!


3

Вугілля деревне , 32 байти

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Порт відповіді Python @ xnor. Пояснення:

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

|х+уу|=х2+у2=(а2-б2)2+(2аб)2=а2+б2х2а22а

≧∕ηθ

у=2абб2а

§≔θ⁰⊘η

2а

Iθ

Передавайте значення на рядок і друкується неявно.


3

Java 8, 84 байти

(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

Порт відповіді Python 2 @xnor 's .

Спробуйте в Інтернеті.

Пояснення:

(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 байт

nOtsн+·t©/¦®;š

Порт відповіді Python 2 @xnor 's .

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

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 байт

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

Порт моєї відповіді Java 8 , але повертає кортеж замість рядка. Я думав, що це було б коротше, але, на жаль, Math.SqrtвимагаюSystem -імпорту в C # .NET, що закінчується на 4 байти довше, а не на 10 байт коротше ..>.>

Декларація лямбда виглядає досить смішно, хоча:

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

Спробуйте в Інтернеті.


1

Perl 6 , 49 байт

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

Спробуйте в Інтернеті!

Вироблена функція приймає вхід як f(b,c,d)(a). Повертає кватерніон як a,(b,c,d).

Пояснення

{;                                             }  # 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.