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

11

Фон

Quaternion - это система счисления, расширяющая комплексные числа. Кватернион имеет следующую форму

a+bi+cj+dk

где - действительные числа, а - три фундаментальных кватернионных единицы . Единицы имеют следующие свойства:a,b,c,di,j,k

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

Обратите внимание, что умножение кватернионов не является коммутативным .

задача

Учитывая нереальный кватернион, вычислите хотя бы один из его квадратных корней.

Как?

Согласно этому ответу Math.SE , мы можем выразить любой нереальный кватернион в следующей форме:

q=a+bu

где - действительные числа, а - мнимый единичный вектор в форме с . Любой такой обладает свойством , поэтому его можно рассматривать как мнимую единицу.a,buxi+yj+zkx2+y2+z2=1uu2=1

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

q2=(a2b2)+2abu

Обратно, учитывая кватернион , мы можем найти квадратный корень из , решив следующие уравненияq=x+yuq

x=a2b2,y=2ab

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

Обратите внимание, что отрицательное действительное число имеет бесконечно много кватернионных квадратных корней, но нереальное кватернион имеет только два квадратных корня .

Вход и выход

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

Выход - один или два кватерниона, которые в квадрате равны входу.

Контрольные примеры

   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
Я ничего не могу поделать: вы должны включить «¯_ (ツ) _ / ¯» в ваш ответ
Барранка
7
Вы уронили это \
Андрей
@ Барранка Готово.
Адам
@ Эндрю обвиняет в этом приложение для Android ... Спасибо, что подняли его :)
Барранка,
2
Было бы лучше, если бы это¯\_(⍨)√¯
Захари
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 для его решения, как в постановке задачи.

XNOR
источник
«Ввод - это нереальный кватернион. Вы можете принять его как четыре действительных (с плавающей запятой) числа в любом порядке и структуре по вашему выбору». Таким образом, вы можете рассматривать его как серию панд или массив numpy. Ряды имеют масштабирование с простым умножением, и есть различные способы получить норму, например (s*s).sum()**.5.
накопление
6

Wolfram Language (Mathematica) , 19 байтов

Sqrt
<<Quaternions`

Попробуйте онлайн!

Mathematica также имеет встроенный Quaternion, но более подробный.


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

user202729
источник
4

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

Основано на прямой формуле, используемой xnor .

Принимает ввод в виде массива.

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

Попробуйте онлайн!

Как?

q=[a,b,c,d]

x=a+a2+b2+c2+d22

И возвращает:

[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
источник
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

Попробуйте онлайн!

XNOR
источник
3

Древесный уголь , 32 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Порт @Xnor's Python ответа. Объяснение:

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

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

≧∕ηθ

y=2abb2a

§≔θ⁰⊘η

2a

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

Порт @xnor 's Python 2 ответа .

Попробуйте онлайн.

Объяснение:

(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©/¦®;š

Порт @xnor 's Python 2 ответа .

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

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 , но возвращает Stuple вместо Tuple. Я думал, что это было бы короче, но, к сожалению, 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)}}

Попробуйте онлайн!

Функция Curried принимает вход как 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
nwellnhof
источник