Skip to main content

deep_causality_num/complex/quaternion_number/
algebra.rs

1/*
2 * SPDX-License-Identifier: MIT
3 * Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
4 */
5use crate::{AbelianGroup, Associative, Distributive, DivisionAlgebra, Quaternion, RealField};
6
7// | Type | `Distributive` | `Associative` | `Commutative` | Trait |
8// | :--- | :---: | :---: | :---: | :--- |
9// | **Quaternion** | ✅ | ✅ | ❌ | `AssociativeRing` |
10
11// Marker Traits
12impl<T: RealField> Associative for Quaternion<T> {}
13impl<T: RealField> Distributive for Quaternion<T> {}
14
15impl<T: RealField> AbelianGroup for Quaternion<T> {}
16
17impl<T: RealField> DivisionAlgebra<T> for Quaternion<T> {
18    /// Returns the conjugate of the quaternion.
19    ///
20    /// For a quaternion `q = w + xi + yj + zk`, its conjugate is `w - xi - yj - zk`.
21    ///
22    /// # Examples
23    ///
24    /// ```
25    /// use deep_causality_num::{Quaternion, DivisionAlgebra};
26    ///
27    /// let q = Quaternion::new(1.0, 2.0, 3.0, 4.0);
28    /// let conj_q : Quaternion<f64>  = q.conjugate();
29    /// assert_eq!(conj_q, Quaternion::new(1.0, -2.0, -3.0, -4.0));
30    /// ```
31    fn conjugate(&self) -> Self {
32        self._conjugate_impl()
33    }
34
35    /// Computes the squared norm (magnitude squared) of the quaternion.
36    ///
37    /// For a quaternion `q = w + xi + yj + zk`, the squared norm is `w^2 + x^2 + y^2 + z^2`.
38    /// This method avoids the square root operation, making it more efficient
39    /// when only relative magnitudes are needed.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use deep_causality_num::{Quaternion, DivisionAlgebra};
45    ///
46    /// let q = Quaternion::new(1.0, 2.0, 3.0, 4.0);
47    /// assert_eq!(q.norm_sqr(), 1.0*1.0 + 2.0*2.0 + 3.0*3.0 + 4.0*4.0);
48    /// ```
49    fn norm_sqr(&self) -> T {
50        self._norm_sqr_impl()
51    }
52
53    /// Returns the inverse of the quaternion.
54    ///
55    /// For a non-zero quaternion `q`, its inverse `q^-1` is `q.conjugate() / q.norm_sqr()`.
56    /// If the quaternion is a zero quaternion, it returns a quaternion with `NaN` components.
57    ///
58    /// # Examples
59    ///
60    /// ```
61    /// use deep_causality_num::{Quaternion, DivisionAlgebra};
62    ///
63    /// let q = Quaternion::new(1.0, 2.0, 3.0, 4.0);
64    /// let inv_q = q.inverse();
65    /// // For a unit quaternion, inverse is its conjugate.
66    /// // For a general quaternion, q * q.inverse() should be identity.
67    /// let identity_q : Quaternion<f64>  = q * inv_q;
68    /// assert!((identity_q.w - 1.0).abs() < 1e-9);
69    /// assert!((identity_q.x - 0.0).abs() < 1e-9);
70    /// assert!((identity_q.y - 0.0).abs() < 1e-9);
71    /// assert!((identity_q.z - 0.0).abs() < 1e-9);
72    ///
73    /// let zero_q = Quaternion::<f64>::new(0.0, 0.0, 0.0, 0.0);
74    /// let inv_zero_q = zero_q.inverse();
75    /// assert!(inv_zero_q.w.is_nan());
76    /// ```
77    fn inverse(&self) -> Self {
78        self._inverse_impl()
79    }
80}