NAME
Sidef::Types::Number::Quaternion - Quaternion number implementation
DESCRIPTION
This class implements quaternions, which are an extension of complex numbers. A quaternion has four components and can be written as a + bi + cj + dk, where a, b, c, d are real numbers and i, j, k are the fundamental quaternion units satisfying:
i² = j² = k² = ijk = -1
Quaternions are particularly useful in 3D graphics, robotics, and physics for representing rotations and orientations. Note that quaternion multiplication is non-commutative (a*b ≠ b*a in general).
SYNOPSIS
var a = Quaternion(1, 2, 3, 4)
var b = Quaternion(5, 6, 7, 8)
say a+b #=> Quaternion(6, 8, 10, 12)
say a-b #=> Quaternion(-4, -4, -4, -4)
say a*b #=> Quaternion(-60, 12, 30, 24)
say b*a #=> Quaternion(-60, 20, 14, 32) # Note: multiplication is non-commutative
say a/b #=> Quaternion(35/87, 4/87, 0, 8/87)
# Basic operations
say a.abs #=> 5.477225575051661 (magnitude)
say a.norm #=> 30 (squared magnitude)
say a.conj #=> Quaternion(1, -2, -3, -4) (conjugate)
say a.inv #=> multiplicative inverse
# Component access
say a.a #=> 1 (real part)
say a.b #=> 2 (i coefficient)
say a.c #=> 3 (j coefficient)
say a.d #=> 4 (k coefficient)
say a.parts #=> [1, 2, 3, 4]
# Power and modular operations
say a**3 #=> a cubed
say a.sqr #=> a squared
say a.powmod(5, 100) #=> (a^5) mod 100
INHERITS
Inherits methods from:
* Sidef::Types::Number::Number
METHODS
!=
a != b
Returns true if quaternions a and b are not equal, false otherwise. Two quaternions are equal if all four components are equal.
Aliases: ne
%
a % b
Returns the remainder of a divided by b. When b is a scalar, applies modulo operation to each component. When b is a quaternion, computes a - b * floor(a/b).
Aliases: mod
&
a & b
Returns the bitwise AND of quaternions a and b. If b is a quaternion, applies AND component-wise. If b is a scalar, applies AND only to the real part.
Aliases: and
*
a * b
Returns the product of a and b using quaternion multiplication. Note that quaternion multiplication is non-commutative (a*b may not equal b*a). If b is a scalar, scales all components by b.
The quaternion product formula is: (a₁ + b₁i + c₁j + d₁k)(a₂ + b₂i + c₂j + d₂k) = (a₁a₂ - b₁b₂ - c₁c₂ - d₁d₂) + (a₁b₂ + b₁a₂ + c₁d₂ - d₁c₂)i + (a₁c₂ - b₁d₂ + c₁a₂ + d₁b₂)j + (a₁d₂ + b₁c₂ - c₁b₂ + d₁a₂)k
Aliases: mul
**
a ** b
Returns a raised to the power b. For integer exponents, uses efficient binary exponentiation. For non-integer exponents, converts to complex number representation first.
Aliases: pow
+
a + b
Returns the sum of a and b. Addition is performed component-wise. If b is a scalar, adds it only to the real part.
Aliases: add
++
a++
Returns the quaternion a incremented by 1 (adds 1 to the real part only).
Aliases: inc
-
a - b
Returns the difference of a and b. Subtraction is performed component-wise. If b is a scalar, subtracts it only from the real part.
Aliases: sub
--
a--
Returns the quaternion a decremented by 1 (subtracts 1 from the real part only).
Aliases: dec
/
a / b
Returns the quotient of a divided by b, computed as a * b.inv().
Aliases: ÷, div
<
a < b
Returns true if quaternion a is less than b based on lexicographic ordering (comparing components in order: a, b, c, d).
Aliases: lt
<<
a << b
Returns a multiplied by 2^b (left shift, equivalent to a * 2**b).
Aliases: lsft, shift_left
<=>
a <=> b
Returns -1, 0, or 1 depending on whether a is less than, equal to, or greater than b using lexicographic ordering. Returns undef if comparison is not defined.
Aliases: cmp
==
a == b
Returns true if quaternions a and b are equal (all components match), false otherwise.
Aliases: eq
>
a > b
Returns true if quaternion a is greater than b based on lexicographic ordering.
Aliases: gt
>>
a >> b
Returns a divided by 2^b (right shift, equivalent to a / 2**b).
Aliases: rsft, shift_right
^
a ^ b
Returns the bitwise XOR of quaternions a and b. If b is a quaternion, applies XOR component-wise. If b is a scalar, applies XOR only to the real part.
Aliases: xor
|
a | b
Returns the bitwise OR of quaternions a and b. If b is a quaternion, applies OR component-wise. If b is a scalar, applies OR only to the real part.
Aliases: or
≤
a ≤ b
Returns true if quaternion a is less than or equal to b based on lexicographic ordering.
Aliases: <=, le
≥
a ≥ b
Returns true if quaternion a is greater than or equal to b based on lexicographic ordering.
Aliases: >=, ge
a
self.a
Returns the real component (first component) of the quaternion. This is the coefficient of the scalar part.
Quaternion(1, 2, 3, 4).a #=> 1
Aliases: re, real
abs
x.abs
Returns the absolute value (magnitude or modulus) of the quaternion, computed as the square root of the norm:
|q| = √(a² + b² + c² + d²)
Quaternion(1, 2, 3, 4).abs #=> 5.477225575051661
b
self.b
Returns the second component of the quaternion (coefficient of i).
Quaternion(1, 2, 3, 4).b #=> 2
c
self.c
Returns the third component of the quaternion (coefficient of j).
Quaternion(1, 2, 3, 4).c #=> 3
ceil
x.ceil
Returns a new quaternion with each component rounded up to the nearest integer.
Quaternion(1.2, 2.7, 3.1, 4.9).ceil #=> Quaternion(2, 3, 4, 5)
conj
x.conj
Returns the conjugate of the quaternion. The conjugate negates the i, j, and k components while keeping the real part unchanged:
conj(a + bi + cj + dk) = a - bi - cj - dk
Quaternion(1, 2, 3, 4).conj #=> Quaternion(1, -2, -3, -4)
The conjugate is useful for division and finding the inverse.
d
self.d
Returns the fourth component of the quaternion (coefficient of k).
Quaternion(1, 2, 3, 4).d #=> 4
dump
x.dump
Returns a string representation of the quaternion in the form "Quaternion(a, b, c, d)".
Quaternion(1, 2, 3, 4).dump #=> "Quaternion(1, 2, 3, 4)"
eval
x.eval(v)
Evaluates the quaternion by substituting value v into each component (useful when components are symbolic expressions or polynomials).
float
x.float
Returns a new quaternion with each component converted to floating-point representation.
floor
x.floor
Returns a new quaternion with each component rounded down to the nearest integer.
Quaternion(1.2, 2.7, 3.1, 4.9).floor #=> Quaternion(1, 2, 3, 4)
inv
x.inv
Returns the multiplicative inverse of the quaternion. The inverse is computed as:
q⁻¹ = conj(q) / norm(q)
where norm(q) = a² + b² + c² + d².
var q = Quaternion(1, 2, 3, 4)
say q * q.inv #=> Quaternion(1, 0, 0, 0) (approximately)
invmod
x.invmod(m)
Returns the modular multiplicative inverse of quaternion x modulo m. This finds a quaternion y such that (x * y) mod m = 1.
is_coprime
n.is_coprime(k)
Returns true if quaternions n and k are coprime, meaning gcd(norm(n), norm(k)) = 1.
is_mone
x.is_mone
Returns true if the quaternion equals -1 (i.e., Quaternion(-1, 0, 0, 0)).
is_one
x.is_one
Returns true if the quaternion equals 1 (i.e., Quaternion(1, 0, 0, 0)).
is_zero
x.is_zero
Returns true if the quaternion equals 0 (i.e., Quaternion(0, 0, 0, 0)).
lift
x.lift
Applies the lift operation to each component of the quaternion (useful for symbolic computations).
neg
x.neg
Returns the negation of the quaternion (negates all four components).
Quaternion(1, 2, 3, 4).neg #=> Quaternion(-1, -2, -3, -4)
new
Quaternion.new(a, b, c, d)
Quaternion(a, b, c, d)
Creates a new quaternion with components a, b, c, d. All parameters default to 0 if not provided.
var q1 = Quaternion(1, 2, 3, 4) # creates 1 + 2i + 3j + 4k
var q2 = Quaternion(5) # creates 5 + 0i + 0j + 0k
var q3 = Quaternion() # creates 0 + 0i + 0j + 0k
Aliases: call
norm
x.norm
Returns the squared magnitude (norm) of the quaternion:
norm(q) = a² + b² + c² + d²
Quaternion(1, 2, 3, 4).norm #=> 30
Note: norm(q) = abs(q)²
parts
self.parts
Returns an array containing all four components of the quaternion [a, b, c, d].
Quaternion(1, 2, 3, 4).parts #=> [1, 2, 3, 4]
powmod
x.powmod(n, m)
Returns (x^n) mod m using efficient modular exponentiation. Uses binary exponentiation algorithm for integer exponents.
pretty
x.pretty
Returns a formatted string representation of the quaternion, converting it to Gaussian complex form for display.
Aliases: stringify
reals
self.reals
Returns the four components as a list: (a, b, c, d).
var (w, x, y, z) = Quaternion(1, 2, 3, 4).reals
round
x.round(r)
Returns a new quaternion with each component rounded to r decimal places (or to nearest integer if r is not specified).
Quaternion(1.234, 2.567, 3.891, 4.123).round(1) #=> Quaternion(1.2, 2.6, 3.9, 4.1)
sgn
x.sgn
Returns the sign (versor) of the quaternion, which is the unit quaternion in the same direction:
sgn(q) = q / |q|
This is useful for extracting rotation information.
sqr
x.sqr
Returns the square of the quaternion (x * x).
Quaternion(1, 2, 3, 4).sqr #=> Quaternion(-28, 4, 6, 8)
to_c
x.to_c
Converts the quaternion to a complex number representation (via Gaussian integers). Returns a nested complex structure.
Aliases: to_n
to_gauss
x.to_gauss
Converts the quaternion to a representation using Gaussian integers (complex numbers with integer real and imaginary parts):
Quaternion(a, b, c, d) → Gauss(Gauss(a, b), Gauss(c, d))
to_s
x.to_s
Returns a string representation of the quaternion.
MATHEMATICAL PROPERTIES
Quaternion Multiplication
Quaternion multiplication follows these rules for the fundamental units:
i² = j² = k² = -1
ij = k, jk = i, ki = j
ji = -k, kj = -i, ik = -j
This makes quaternion multiplication non-commutative.
Norm Properties
norm(q₁ * q₂) = norm(q₁) * norm(q₂)
norm(q) = q * conj(q) = conj(q) * q
Inverse
q * q⁻¹ = q⁻¹ * q = 1
q⁻¹ = conj(q) / norm(q)
EXAMPLES
# Creating quaternions
var q1 = Quaternion(1, 0, 0, 0) # Real quaternion
var q2 = Quaternion(0, 1, 0, 0) # Pure imaginary (i)
var q3 = Quaternion(0, 0, 1, 0) # Pure imaginary (j)
var q4 = Quaternion(0, 0, 0, 1) # Pure imaginary (k)
# Verifying fundamental properties
say q2**2 #=> Quaternion(-1, 0, 0, 0)
say q2*q3 #=> Quaternion(0, 0, 0, 1) (= k)
say q3*q2 #=> Quaternion(0, 0, 0, -1) (= -k)
# Unit quaternion (rotation)
var angle = 90.deg2rad
var axis = [0, 0, 1] # Z-axis
var w = cos(angle/2)
var (x, y, z) = axis.map { _ * sin(angle/2) }...
var rotation = Quaternion(w, x, y, z)
say rotation.norm #=> 1 (unit quaternion)
# Quaternion division
var a = Quaternion(1, 2, 3, 4)
var b = Quaternion(5, 6, 7, 8)
say a/b #=> Quaternion(35/87, 4/87, 0, 8/87)
say (a/b)*b #=> approximately equal to a
SEE ALSO
Sidef::Types::Number::Number, Sidef::Types::Number::Gauss, Sidef::Types::Number::Complex