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}