쿼터니언 곱하기


13

두 쿼터니언의 쿼터니언 곱을 계산하는 명명 된 함수 또는 프로그램을 작성하십시오. 가능한 적은 바이트를 사용하십시오.

쿼터니언

쿼터니언 은 복소수를 더 확장하는 실수의 확장입니다. i쿼터니언 은 단일 허수 단위 대신 i,j,k관계를 만족하는 3 개의 허수 단위 를 사용 합니다.

i*i = j*j = k*k = -1
i*j =  k
j*i = -k
j*k =  i
k*j = -i
k*i =  j
i*k = -j

( 위키 백과 페이지에도이 표가 있습니다 .)

다시 말해, 각 허수 단위는로 제곱되고 -1, 두 개의 서로 다른 허수 단위의 곱은 +/-순환 순서 (i,j,k)가 존중 되는지 여부 (즉, 오른쪽 규칙 )에 따라 나머지 세 번째 입니다. 따라서 곱셈의 순서가 중요합니다.

일반적인 쿼터니언은 실수 부와 3 개의 허수 단위의 선형 조합입니다. 따라서 4 개의 실수로 설명됩니다 (a,b,c,d).

x = a + b*i + c*j + d*k

따라서 우리는 분배 속성을 사용하여 두 개의 쿼터니언을 곱할 수 있습니다. 단위를 올바른 순서로 곱할 때주의를 기울이고 결과에서 용어처럼 그룹화합니다.

(a + b*i + c*j + d*k) * (e + f*i + g*j + h*k)
= (a*e - b*f - c*g - d*h)    +
  (a*f + b*e + c*h - d*g)*i  +
  (a*g - b*h + c*e + d*f)*j  +
  (a*h + b*g - c*f + d*e)*k

이런 식으로 쿼터니언 곱셈은 한 쌍의 4 튜플에서 단일 4 튜플까지의 맵으로 볼 수 있습니다. 이는 구현하라는 요청입니다.

체재

프로그램 이나 명명 된 함수를 작성해야 합니다 . 프로그램은 STDIN에서 입력을 받아 결과를 인쇄해야합니다. 함수는 함수 입력을 받아서 출력을 반환 (인쇄하지 않음)해야합니다.

입력 및 출력 형식이 유연합니다. 입력은 8 개의 실수 (2 개의 쿼터니언에 대한 계수)이며 출력은 4 개의 실수로 구성됩니다. 입력은 8 개의 숫자, 4 개의 두 목록, 2x4 행렬 등일 수 있습니다. 입력 / 출력 형식이 같을 필요는 없습니다. (1,i,j,k)계수의 순서는 사용자에게 달려 있습니다.

계수는 음수이거나 완전하지 않을 수 있습니다. 실제 정밀도 또는 오버플로에 대해 걱정하지 마십시오.

금지됨 : 쿼터니언 또는 그에 상응하는 기능 또는 유형.

테스트 사례

이들은 (1,i,j,k)계수 형식입니다.

[[12, 54, -2, 23], [1, 4, 6, -2]] 
 [-146, -32, 270, 331]

[[1, 4, 6, -2], [12, 54, -2, 23]] 
 [-146, 236, -130, -333]

[[3.5, 4.6, -0.24, 0], [2.1, -3, -4.3, -12]] 
 [20.118, 2.04, 39.646, -62.5]

참조 구현

파이썬에서 함수로 :

#Input quaternions: [a,b,c,d], [e,f,g,h]
#Coeff order: [1,i,j,k]

def mult(a,b,c,d,e,f,g,h):
    coeff_1 = a*e-b*f-c*g-d*h
    coeff_i = a*f+b*e+c*h-d*g
    coeff_j = a*g-b*h+c*e+d*f
    coeff_k = a*h+b*g-c*f+d*e

    result = [coeff_1, coeff_i, coeff_j, coeff_k]
    return result

답변:


4

CJam, 49 45 39 바이트

"cM-^\M-^G-^^KM-zP"256bGbq~m*f{=:*}4/{:-W*}/W*]`

코드에는 인쇄 할 수없는 문자가 포함되어 있으므로 위의 캐럿 및 M 표기법을 사용합니다.

2 바이트를 추가로 사용하면 이러한 문자를 피할 수 있습니다.

6Z9C8 7YDXE4BFA5U]q~m*f{=:*}4/{:-W*}/W*]`

이 버전을 온라인으로 사용해 볼 수 있습니다 : CJam 통역사

테스트 사례

를 계산하려면 (a + bi + cj + dk) * (e + fi + gj + hk)다음 입력을 사용하십시오.

[ d c b a ] [ h g f e ]

출력은

[ z y x w ]

이는 쿼터니언에 해당합니다 w + xi + yj + zk.

$ base64 -d > product.cjam <<< ImOchy0eS/pQIjI1NmJHYnF+bSpmez06Kn00L3s6LVcqfS9XKl1g
$ wc -c product.cjam
39 product.cjam
$ LANG=en_US cjam product.cjam <<< "[23 -2 54 12] [-2 6 4 1]"; echo
[331 270 -32 -146]
$ LANG=en_US cjam product.cjam <<< "[-2 6 4 1] [23 -2 54 12]"; echo
[-333 -130 236 -146]
$ LANG=en_US cjam product.cjam <<< "[0 -0.24 4.6 3.5] [-12 -4.3 -3 2.1]"; echo
[-62.5 39.646 2.04 20.118]

작동 원리

6Z9C8 7YDXE4BFA5U]  " Push the array [ 6 3 9 12 8 7 2 13 1 14 4 11 15 10 5 0].         ";
q~                  " Read from STDIN and interpret the input.                         ";
m*                  " Compute the cartesian product of the input arrays.               ";
f                   " Execute the following for each element of the first array:       ";
{                   " Push the cartesian product (implicit).                           ";
    =               " Retrieve the corresponding pair of coefficients.                 ";
    :*              " Calculate their product.                                         ";
}                   "                                                                  ";
4/                  " Split into chunks of 4 elements.                                 ";
{:-W*}/             " For each, subtract the first element from the sum of the others. ";
W*                  " Multiply the last integers (coefficient of 1) by -1.             ";
]`                  " Collect the results into an array and stringify it.              ";

6

파이썬 (83)

r=lambda A,B,R=range(4):[sum(A[m]*B[m^p]*(-1)**(14672>>p+4*m)for m in R)for p in R]

두 개의 목록 A,B[1,i,j,k]순서대로 가져와 같은 형식으로 결과를 반환합니다.

핵심 아이디어는 [1,i,j,k]indices에 대응하여 인덱스 [0,1,2,3]를 XOR하여 제품의 인덱스를 얻을 수 있다는 것입니다. 따라서 색인 p에 포함 되는 용어는 XOR을 색인하는 용어 p이며 따라서 제품 A[m]*B[m^p]입니다.

표지판이 제대로 작동하도록 만드는 것만 남아 있습니다. 내가 찾은 가장 짧은 방법은 단순히 마법의 문자열로 코드를 작성하는 것이 었습니다. 의 16 가지 가능성 (m,p)은로 숫자 015바뀝니다 p+4*m. 14672이진수 의 숫자 는 부호가 필요한 1곳에 -1있습니다. , 그것에게를 장소의 적절한 수의 이동에 의해 1또는 0이렇게 마지막 자리에 바람이, 홀수 또는 짝수 번호를 만들고, 그리고 (-1)**중 하나입니다 1또는 -1필요에 따라.


XOR 부분은 순수한 천재입니다.
Dennis

3

파이썬 -90 75 72 69

순수 파이썬, 라이브러리 없음-90 :

m=lambda a,b,c,d,e,f,g,h:[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

파이썬에서이 "기본"솔루션을 단축하는 것은 아마도 꽤 어려울 것입니다. 그러나 다른 사람들이 생각해 낼 수 있을지 궁금합니다. :)


NumPy 사용 -75 72 69 :

입력과 출력이 다소 융통성이 있기 때문에 NumPy 함수를 사용하고 스칼라 벡터 표현을 활용할 수 있습니다 .

import numpy
m=lambda s,p,t,q:[s*t-sum(p*q),s*q+t*p+numpy.cross(p,q)]

입력 인자 st두 쿼터니온 (실수 부)의 스칼라 부분이며, pq해당 벡터 부분 (허수 단위)이다. 출력은 결과 쿼터니언의 스칼라 부분과 벡터 부분을 포함하는 목록이며, 후자는 NumPy 배열로 표시됩니다.

간단한 테스트 스크립트 :

for i in range(5):
    a,b,c,d,e,f,g,h=np.random.randn(8)
    s,p,t,q=a, np.array([b, c, d]), e, np.array([f, g, h])
    print mult(a, b, c, d, e, f, g, h), "\n", m(s,p,t,q)

( mult(...)OP의 참조 구현 임)

산출:

[1.1564241702553644, 0.51859264077125156, 2.5839001110572792, 1.2010364098925583] 
[1.1564241702553644, array([ 0.51859264,  2.58390011,  1.20103641])]
[-1.8892934508324888, 1.5690229769129256, 3.5520713781125863, 1.455726589916204] 
[-1.889293450832489, array([ 1.56902298,  3.55207138,  1.45572659])]
[-0.72875976923685226, -0.69631848934167684, 0.77897519489219036, 1.4024428845608419] 
[-0.72875976923685226, array([-0.69631849,  0.77897519,  1.40244288])]
[-0.83690812141836401, -6.5476014589535243, 0.29693969165495304, 1.7810682337361325] 
[-0.8369081214183639, array([-6.54760146,  0.29693969,  1.78106823])]
[-1.1284033842268242, 1.4038096725834259, -0.12599103441714574, -0.5233468317643214] 
[-1.1284033842268244, array([ 1.40380967, -0.12599103, -0.52334683])]

2

하스켈, 85

m a b c d e f g h=[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

Haskell로 포팅하면 몇 개의 문자가 절약됩니다.)


2

매스 매 티카 83 50

아마 더 많은 골프를하실 수 있습니다 ..

p = Permutations;
f = #1.(Join[{{1, 1, 1, 1}}, p[{-1, 1, -1, 1}][[1 ;; 3]]] p[#2][[{1, 8, 17, 24}]]) &

공백과 줄 바꿈은 계산되지 않으며 필요하지 않습니다.

용법:

f[{a,b,c,d},{e,f,g,h}]        (* => {x,w,y,z}   *)


편집 작동 방식.

Mathematica 함수 Permutations#2(두 번째 인수) 의 가능한 모든 순열을 만듭니다 . 이 24 순열가 있지만 우리는 만하면 {e,f,g,h}, {f,e,h,g}, {g,h,e,f},와 {h,g,f,e}. 이들은 첫 번째, 8 번째, 17 번째 및 24 번째 순열입니다. 그래서 코드

p[#2][[{1,8,17,24}]]

두 번째 인수의 순열에서이를 정확하게 선택하여 행렬로 반환합니다. 그러나 그들은 아직 정확한 부호가 없습니다. 이 코드 p[{-1,1,-1,1}][[1;;3]]는 올바른 부호가있는 3x4 행렬을 반환합니다. 우리는 {1,1,1,1}을 사용하여 접두사 Join를 두어 Times두 행렬 사이에 정규 곱셈 ( , 또는 서로를 쓴 후 여기에서와 같이)을 사용하여 Mathematica에서 요소별로 곱셈을 만듭니다.

마지막으로

(Join[{{1, 1, 1, 1}}, p[{-1, 1, -1, 1}][[1 ;; 3]]] p[#2][[{1, 8, 17, 24}]])

매트릭스입니다

 e  f  g  h
-f  e -h  g
-g  h  e -f
-h -g  f  e

{a,b,c,d}(첫 번째 인수 #1)와 이전 행렬 사이에 행렬을 곱 하면 원하는 결과가 나타납니다.



2 짧은 코드 편집

Falko의 Python 코드에서 영감을 받아 쿼터니언을 스칼라와 벡터 부분으로 나누고 Mathematica의 내장 명령 Cross을 사용하여 벡터 부분 의 교차 곱을 계산합니다.

f[a_, A_, b_, B_] := Join[{a*b - A.B}, a*B + b*A + Cross[A, B]]

용법:

f[a,{b,c,d},e,{f,g,h}]        (* => {x,w,y,z}   *)

이것이 어떻게 작동하는지 설명해 주시겠습니까? 무엇입니까 1, 8, 17, 24?
xnor

1

파이썬, 94

가장 간단한 방법은 너무 길지 않습니다.

def m(a,b,c,d,e,f,g,h):return[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

1

자바 스크립트 ES6-86

f=(a,b,c,d,e,f,g,h)=>[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

1

루아-99

그럴 수도 있습니다.

_,a,b,c,d,e,f,g,h=unpack(arg)print(a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e)

루아의 "unpack ()"은 테이블의 요소를 해제합니다. 따라서 'arg'테이블은 모든 명령 행 입력이 저장 arg[0]되는 위치입니다 (프로그램의 파일 이름을 포함하여 파일이 삭제됨).


1

Python, 58 56 자

m=lambda x,y,z,w:(x*z-y*(2*w.real-w),x*w+y*(2*z.real-z))

나는 입 / 출력 형식의 위 글룸 을 매우 자유롭게 사용합니다. 입력은 4 개의 복소수이며 다음과 같이 인코딩됩니다.

x = a+b*i
y = c+d*i
z = e+f*i
w = g+h*i

이는 유사한 형식 복소수의 쌍을 출력한다, 상기 한 쌍의 제 실제 및 부호화 i부, 제 코딩하는 jk부품.

이 작동을 보려면 첫 번째 쿼터니언은 x+y*j이고 두 번째 쿼터니언은 입니다 z+w*j. 가상의 숫자에 대해 = 를 평가 (x+y*j)*(z+w*j)하고 깨달으십시오 .j*tconj(t)*jt


매우 영리한! 쿼터니언이 식에서 볼 때 복잡한 계수를 가진 복소수와 곱하는 것처럼 보이는 이유를 알고 있습니까?
xnor

신경 쓰지 마, 내가 지금 설명하는 방법에서 이해 i하고 j내부 및 외부 복잡한 계수 등과 같은 역할을합니다. 정말 매력적입니다!
xnor

conj 호출이 2/5 이상의 문자를 차지하는 방식이 재미 있습니다. 나는 당신이 각각을 사용하여 숯을 면도 할 수 있다고 생각합니다 (2*w.real-w). abs(w)**2/w작동하지만 0입니다. 문자열 대체를 가진 exec조차 가치가 있습니까? `
xnor

1

속삭임 v2 , 396 바이트

> 1
> 2
> 0
> 4
> Input
> Input
>> 6ᶠ2
>> 6ᵗ2
>> 7ⁿ3
>> 7ⁿ1
>> 10‖9
>> 8ⁿ3
>> 8ⁿ1
>> 13‖12
>> 7‖8
>> 11‖14
>> 8‖7
>> 14‖11
>> 15‖16
>> 19‖17
>> 20‖18
>> 4⋅5
>> L⋅R
>> Each 23 22 21
> [1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1]
>> Each 23 24 25
>> 26ᶠ4
>> 26ᵗ4
>> 28ᶠ4
> 8
>> 26ᵗ30
>> 31ᶠ4
>> 31ᵗ4
>> ∑27
>> ∑29
>> ∑32
>> ∑33
>> Output 34 35 36 37

온라인으로 사용해보십시오!

형태로 입력을받습니다

[a, b, c, d]
[e, f, g, h]

다음과 같이 출력

w
x
y
z

를 나타 내기 위해q=w+xi+yj+zk

이 답변의 구조 트리는 다음과 같습니다.

나무

이 답변의 좋은 덩어리는 Whispers의 두 가지 주요 결함에서 비롯됩니다.

  • 배열을 반전시키는 기능이 없음
  • 데카르트 곱 계산에서 집합의 사용

따라서 코드를 3 개의 섹션으로 나눌 수 있습니다.

작동 원리

명확성과 간결성을 위해 다음 정의를 사용합니다.

q=a+bi+cj+dk
p=e+fi+gj+hk
r=w+xi+yj+zk,(qp=r)
A=[a,b,c,d]
B=[e,f,g,h]
C=[w,x,y,z]

섹션 1 : 순열AB

첫 번째 섹션은 라인 1 에서 라인 22 까지 가장 길다 .

> 1
> 2
> 0
> 4
> Input
> Input
>> 6ᶠ2
>> 6ᵗ2
>> 7ⁿ3
>> 7ⁿ1
>> 10‖9
>> 8ⁿ3
>> 8ⁿ1
>> 13‖12
>> 7‖8
>> 11‖14
>> 8‖7
>> 14‖11
>> 15‖16
>> 19‖17
>> 20‖18
>> 4⋅5

BABBA

B1=[e,f,g,h]
B2=[f,e,h,g]
B3=[g,h,e,f]
B4=[h,g,f,e]

BBBB2B4

>> 7ⁿ3
>> 7ⁿ1
>> 10‖9

[f,e]

>> 8ⁿ3
>> 8ⁿ1
>> 13‖12

[h,g]B1,B2,B3B4BTATA4

AT=[a,b,c,d,a,b,c,d,a,b,c,d,a,b,c,d]
BT=[e,f,g,h,f,e,h,g,g,h,e,f,h,g,f,e]

BTATqp

섹션 2 : 표시 및 제품

ATBTqp

> [1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1]

SAT,BTS[[a,e,1],[b,f,1],,[e,f,1],[d,e,1]]D=[ae,bf,,ef,de]

섹션 3 : 파티션 및 최종 합계

qpqp

> 4

54DD

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.