z ← {larg}(fn ##.H)rarg ⍝ Quaternion arithmetic Operator [H] is a partial model for Quaternion arithmetic. Argument arrays [larg] and [rarg] each have a trailing axis of length 4. In other words, a quaternion array of shape S is represented as a shape (S,4) array of real numb- bers. NB: unlike operators →nats← and →rats←, [H] deals in multi-item arrays of any rank. Operand function [fn] may currently be one of: Monadic Dyadic ------- ------ + conjugate sum - negative difference × direction product ÷ reciprocal quotient | magnitude · Together with these special operations: ⌽ ⍺-rotation of points ⍵, where ⍺ is (a i j k), where [a] is the magnitude of the rotation in radians and [i j k] is the direction of a rotation axis through the origin. ⍎ input conversion from ..i..j..k.. form to 4-tuple, ⍕ output conversion from 4-tuple to ..i..j..k.. form. This is a work in progress; more operand functions may be added later. Monadic ⍎ and ⍕ convert between character '..i..j..k..' and numeric 4-vectors: ⍕H 1 2 3 4 ⍝ numeric 4-tuple to character 1i2j3k4 ⍎H '5i6j7k8' ⍝ character to numeric 4-tuple 5 6 7 8 ⍎H'1i2j3k4 5i6j7k8' ⍝ quaternion vector ←→ real matrix 1 2 3 4 5 6 7 8 Historical Note --------------- Sir William Rowan Hamilton's insight into the nature of quaternions occurred while walking along The Royal Canal in Dublin on 16th October 1843. He famously stopped to carve the defining equations: i² = j² = k² = ijk = -1 on the stonework of Brougham (Broom) Bridge, where a plaque now commemorates the event. The diagonal of the following display illustrates the first parts of the above rule and the off-diagonal values show that quaternion multiplication is non- commutative: ij = k = -ji; jk = i = -kj; ki = j = -ik. ijk ← ↓ ⍎H'0i1 0j1 0k1' ⍝ unit vectors: i j k ⍕H¨ ijk ∘.(×H) ijk ⍝ i² = j² = k² = -1 ┌────┬────┬────┐ │¯1 │0k1 │0j¯1│ ├────┼────┼────┤ │0k¯1│¯1 │0i1 │ ├────┼────┼────┤ │0j1 │0i¯1│¯1 │ └────┴────┴────┘ and: ⍕H ⊃×H/ ijk ⍝ ijk = -1 ¯1 Ref: https://en.wikipedia.org/wiki/Quaternion Ref: https://en.wikipedia.org/wiki/William_Rowan_Hamilton Thanks to Bob Smith for the reference to Caley-Dixon product in his paper: "Hypercomplex Numbers in APL". See http://www.sudleyplace.com/APL Technical notes: Internally, it is convenient to change the quaternion-array representation from an (S,4)-array of reals to an (S,2)-array of complex numbers. Doing so simplif- ies the multiplication function [mul]. Quaternion conjugate +1i2j3k4 → 1i¯2j¯3k¯4 is interesting. As a complex pair: +H(c0,c1) → (+c0,-c1) which can be coded in tacit (function train) form as: conj ← ↑((+⊣),(-⊢))/ ⍝ conjugate Checking the model with https://www.wolframalpha.com: quaternion(1,2,3,4) * quaternion(5,6,7,8) ⍝ WolframAlpha multiply -> -60 + 12i + 30j + 24k 1 2 3 4 ×H 5 6 7 8 ⍝ Model multiply ¯60 12 30 24 unit(quaternion(1 2 3 4)) ⍝ WolframAlpha norm/unit -> sqrt(30) (4↑30*0.5) ≡ |H 1 2 3 4 ⍝ Model norm/unit 1 Examples dp ← {(10*-⍺)×⌊0.5+⍵×10*⍺} ⍝ rounded to ⍺ decimal places ∆ ← ⍕H∘(2∘dp) ⍝ format of rounded result S ← ⍳4 ⍝ quaternion scalar M ← 2 3 4⍴⍳24 ⍝ .. matrix ∆ M ⍝ formatted matrix 1i2j3k4 5i6j7k8 9i10j11k12 13i14j15k16 17i18j19k20 21i22j23k24 ∆ +H M ⍝ conjugate (q*) 1i¯2j¯3k¯4 5i¯6j¯7k¯8 9i¯10j¯11k¯12 13i¯14j¯15k¯16 17i¯18j¯19k¯20 21i¯22j¯23k¯24 ∆ ÷H M ⍝ reciprocal 0.03i¯0.07j¯0.1k¯0.13 0.03i¯0.03j¯0.04k¯0.05 0.02i¯0.02j¯0.02k¯0.03 0.02i¯0.02j¯0.02k¯0.02 0.01i¯0.01j¯0.01k¯0.01 0.01i¯0.01j¯0.01k¯0.01 ∆ |H M ⍝ norm 5.48 13.19 21.12 29.09 37.07 45.06 ∆ |H ⍎H '2i4j5k6' ⍝ "Hamiltonian quadruple" cf Pythagorean triple 9 ∆ ×H M ⍝ direction (unit versor) 0.18i0.37j0.55k0.73 0.38i0.45j0.53k0.61 0.43i0.47j0.52k0.57 0.45i0.48j0.52k0.55 0.46i0.49j0.51k0.54 0.47i0.49j0.51k0.53 ∆ S +H M ⍝ sum 2i4j6k8 6i8j10k12 10i12j14k16 14i16j18k20 18i20j22k24 22i24j26k28 ∆ S -H M ⍝ difference 0 ¯4i¯4j¯4k¯4 ¯8i¯8j¯8k¯8 ¯12i¯12j¯12k¯12 ¯16i¯16j¯16k¯16 ¯20i¯20j¯20k¯20 ∆ S ×H M ⍝ product ¯28i4j6k8 ¯60i12j30k24 ¯92i20j54k40 ¯124i28j78k56 ¯156i36j102k72 ¯188i44j126k88 ∆ M ×H S ⍝ product is non-commutative ¯28i4j6k8 ¯60i20j14k32 ¯92i36j22k56 ¯124i52j30k80 ¯156i68j38k104 ¯188i84j46k128 ∆ M ×H +H M ⍝ qq* is real 30 174 446 846 1374 2030 ∆ M ÷H S ⍝ right quotient M×(÷S) 1 2.33i¯0.27k¯0.53 3.67i¯0.53k¯1.07 5i¯0.8k¯1.6 6.33i¯1.07k¯2.13 7.67i¯1.33k¯2.67 ∆ (÷H S)×H M ⍝ left quotient (÷S)×M 1 2.33j¯0.53k¯0.27 3.67j¯1.07k¯0.53 5j¯1.6k¯0.8 6.33j¯2.13k¯1.07 7.67j¯2.67k¯1.33 ⊢cube ← 0,⍉2 2 2⊤0 to 7 ⍝ unit cube at origin 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 ⍝ 15 dp (round to 15 decimal places), in the following, smooths the small ⍝ inaccuracies caused by the machine's approximate representation of pi. spin ← {15 dp(○⍺÷180)⌽H ⍵} ⍝ ⍵ rotated ⊃⍺° about 1↓⍺ vector 120 1 1 1 spin cube ⍝ 120° rotation about 1 1 1 diagonal 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 1 ⍕H ↑ cube (120 1 1 1 spin cube) ⍝ formatted cube and 120° rotation 0 0k1 0j1 0j1k1 0i1 0i1k1 0i1j1 0i1j1k1 0 0i1 0k1 0i1k1 0j1 0i1j1 0j1k1 0i1j1k1 M ≡ ⍎H ⍕H M ⍝ check ⍎ ⍕ round-trip 1 See also: numbers nats rats Back to: contents Back to: Workspaces