Skip to main content

deep_causality_num_complex/complex/quaternion_number/
arithmetic.rs

1/*
2 * SPDX-License-Identifier: MIT
3 * Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
4 */
5use crate::{One, Quaternion, RealField, Zero};
6use core::iter::{Product, Sum};
7use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
8
9// Sum
10impl<F: RealField> Sum for Quaternion<F> {
11    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
12        iter.fold(Quaternion::zero(), |acc, x| acc + x)
13    }
14}
15
16// Product
17impl<F: RealField> Product for Quaternion<F> {
18    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
19        iter.fold(Quaternion::one(), |acc, x| acc * x)
20    }
21}
22
23// Add
24impl<T: RealField> Add for Quaternion<T> {
25    type Output = Self;
26    fn add(self, other: Self) -> Self {
27        Quaternion {
28            w: self.w + other.w,
29            x: self.x + other.x,
30            y: self.y + other.y,
31            z: self.z + other.z,
32        }
33    }
34}
35
36// AddAssign
37impl<T: RealField> AddAssign for Quaternion<T> {
38    #[inline]
39    fn add_assign(&mut self, other: Self) {
40        self.w += other.w;
41        self.x += other.x;
42        self.y += other.y;
43        self.z += other.z;
44    }
45}
46
47// Sub
48impl<F: RealField> Sub for Quaternion<F> {
49    type Output = Self;
50
51    fn sub(self, other: Self) -> Self {
52        Quaternion {
53            w: self.w - other.w,
54            x: self.x - other.x,
55            y: self.y - other.y,
56            z: self.z - other.z,
57        }
58    }
59}
60
61impl<F: RealField> SubAssign for Quaternion<F> {
62    fn sub_assign(&mut self, other: Self) {
63        self.w -= other.w;
64        self.x -= other.x;
65        self.y -= other.y;
66        self.z -= other.z;
67    }
68}
69
70// Mul (Quaternion multiplication)
71impl<F: RealField> Mul for Quaternion<F> {
72    type Output = Self;
73    fn mul(self, other: Self) -> Self {
74        let (w1, x1, y1, z1) = (self.w, self.x, self.y, self.z);
75        let (w2, x2, y2, z2) = (other.w, other.x, other.y, other.z);
76
77        Quaternion {
78            w: w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2,
79            x: w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2,
80            y: w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2,
81            z: w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2,
82        }
83    }
84}
85impl<F: RealField> MulAssign for Quaternion<F> {
86    fn mul_assign(&mut self, other: Self) {
87        *self = *self * other;
88    }
89}
90
91// Mul (Scalar multiplication)
92impl<F: RealField> Mul<F> for Quaternion<F> {
93    type Output = Self;
94
95    fn mul(self, scalar: F) -> Self {
96        Quaternion {
97            w: self.w * scalar,
98            x: self.x * scalar,
99            y: self.y * scalar,
100            z: self.z * scalar,
101        }
102    }
103}
104
105impl<F: RealField> MulAssign<F> for Quaternion<F> {
106    fn mul_assign(&mut self, scalar: F) {
107        self.w *= scalar;
108        self.x *= scalar;
109        self.y *= scalar;
110        self.z *= scalar;
111    }
112}
113
114// Div (Quaternion division)
115#[allow(clippy::suspicious_arithmetic_impl)]
116impl<F: RealField> Div for Quaternion<F> {
117    type Output = Self;
118
119    fn div(self, other: Self) -> Self {
120        self * other._inverse_impl()
121    }
122}
123
124// DivAssign
125impl<F: RealField> DivAssign for Quaternion<F> {
126    fn div_assign(&mut self, other: Self) {
127        *self = *self / other;
128    }
129}
130
131// Div (Scalar division)
132impl<F: RealField> Div<F> for Quaternion<F> {
133    type Output = Self;
134
135    fn div(self, scalar: F) -> Self {
136        let inv_scalar = F::one() / scalar;
137        Quaternion {
138            w: self.w * inv_scalar,
139            x: self.x * inv_scalar,
140            y: self.y * inv_scalar,
141            z: self.z * inv_scalar,
142        }
143    }
144}