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

REFERENCES

https://en.wikipedia.org/wiki/Quaternion