Skip to main content

deep_causality_num/complex/complex_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::{Complex, RealField};
6use core::iter::{Product, Sum};
7use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8
9// Implement Sum trait
10impl<T: RealField> Sum for Complex<T> {
11    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
12        iter.fold(Self::new(T::zero(), T::zero()), |acc, x| acc + x)
13    }
14}
15
16// Implement Product trait
17impl<T: RealField> Product for Complex<T> {
18    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
19        iter.fold(Self::new(T::one(), T::zero()), |acc, x| acc * x)
20    }
21}
22
23// Add
24impl<T: RealField> Add for Complex<T> {
25    type Output = Self;
26    #[inline]
27    fn add(self, rhs: Self) -> Self {
28        Self::new(self.re + rhs.re, self.im + rhs.im)
29    }
30}
31
32// AddAssign
33impl<T: RealField> AddAssign for Complex<T> {
34    #[inline]
35    fn add_assign(&mut self, rhs: Self) {
36        self.re += rhs.re;
37        self.im += rhs.im;
38    }
39}
40
41// Scalar Add
42impl<T: RealField> Add<T> for Complex<T> {
43    type Output = Self;
44    #[inline]
45    fn add(self, rhs: T) -> Self {
46        Self::new(self.re + rhs, self.im)
47    }
48}
49
50// Scalar AddAssign
51impl<T: RealField> AddAssign<T> for Complex<T> {
52    #[inline]
53    fn add_assign(&mut self, rhs: T) {
54        self.re += rhs;
55    }
56}
57
58// Sub
59impl<T: RealField> Sub for Complex<T> {
60    type Output = Self;
61    #[inline]
62    fn sub(self, rhs: Self) -> Self {
63        Self::new(self.re - rhs.re, self.im - rhs.im)
64    }
65}
66
67// SubAssign
68impl<T: RealField> SubAssign for Complex<T> {
69    #[inline]
70    fn sub_assign(&mut self, rhs: Self) {
71        self.re -= rhs.re;
72        self.im -= rhs.im;
73    }
74}
75
76// Scalar Sub
77impl<T: RealField> Sub<T> for Complex<T> {
78    type Output = Self;
79    #[inline]
80    fn sub(self, rhs: T) -> Self {
81        Self::new(self.re - rhs, self.im)
82    }
83}
84
85// Scalar SubAssign
86impl<T: RealField> SubAssign<T> for Complex<T> {
87    #[inline]
88    fn sub_assign(&mut self, rhs: T) {
89        self.re -= rhs;
90    }
91}
92
93// Mul
94impl<T: RealField> Mul for Complex<T> {
95    type Output = Self;
96    #[inline]
97    fn mul(self, rhs: Self) -> Self {
98        Self::new(
99            self.re * rhs.re - self.im * rhs.im,
100            self.re * rhs.im + self.im * rhs.re,
101        )
102    }
103}
104
105// MulAssign
106impl<T: RealField> MulAssign for Complex<T> {
107    #[inline]
108    fn mul_assign(&mut self, rhs: Self) {
109        let re = self.re * rhs.re - self.im * rhs.im;
110        let im = self.re * rhs.im + self.im * rhs.re;
111        self.re = re;
112        self.im = im;
113    }
114}
115
116// Scalar Mul
117impl<T: RealField> Mul<T> for Complex<T> {
118    type Output = Self;
119    #[inline]
120    fn mul(self, rhs: T) -> Self {
121        Self::new(self.re * rhs, self.im * rhs)
122    }
123}
124
125// Scalar MulAssign
126impl<T: RealField> MulAssign<T> for Complex<T> {
127    #[inline]
128    fn mul_assign(&mut self, rhs: T) {
129        self.re *= rhs;
130        self.im *= rhs;
131    }
132}
133
134// Div
135impl<T: RealField> Div for Complex<T> {
136    type Output = Self;
137    // Suppress False Positive lint
138    // https://rust-lang.github.io/rust-clippy/rust-1.91.0/index.html#suspicious_arithmetic_impl
139    #[allow(clippy::suspicious_arithmetic_impl)]
140    #[inline]
141    fn div(self, rhs: Self) -> Self {
142        self * rhs._inverse_impl()
143    }
144}
145
146// DivAssign
147impl<T: RealField> DivAssign for Complex<T> {
148    // Suppress False Positive lint
149    #[allow(clippy::suspicious_op_assign_impl)]
150    #[inline]
151    fn div_assign(&mut self, rhs: Self) {
152        *self *= rhs._inverse_impl();
153    }
154}
155
156// Scalar Div
157impl<T: RealField> Div<T> for Complex<T> {
158    type Output = Self;
159    #[inline]
160    fn div(self, rhs: T) -> Self {
161        Self::new(self.re / rhs, self.im / rhs)
162    }
163}
164
165// Scalar DivAssign
166impl<T: RealField> DivAssign<T> for Complex<T> {
167    #[inline]
168    fn div_assign(&mut self, rhs: T) {
169        self.re /= rhs;
170        self.im /= rhs;
171    }
172}
173
174// Neg
175impl<T: RealField> Neg for Complex<T> {
176    type Output = Self;
177    #[inline]
178    fn neg(self) -> Self {
179        Self::new(-self.re, -self.im)
180    }
181}