1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//!
//! Algebraic trait implementations for _complex_ numbers.
//!
//! The complex numbers (ℂ) form a _field_. We assume the
//! _real_ and _imaginary_ parts--or _components_--of a complex number
//! are _real_ numbers (or some numeric approximation to ℝ,
//! e.g. floating point values).
//!
//! In the absence of a complex number type in the Rust standard
//! library, the complex number type used here is from the very handy
//! [num] crate.
//!
#![doc(include = "../doc/references.md")]

use prelude::*;
use std::ops::*;
pub use num::traits::*;
pub use num::complex::*;


///
/// Numeric equality for complex types.
///
impl<T: NumEq> NumEq for Complex<T> {

  /// The numeric error type is the component error type.
  type Error = T::Error;


  /// Equality is component-wise numeric equality.
  fn num_eq(&self, other: &Self, eps: &Self::Error) -> bool {
    let re = self.re.num_eq(&other.re, eps);
    let im = self.im.num_eq(&other.im, eps);

    re && im
  }
}


/// Shorthand type alias for real number complex components.
pub trait Real: Float + NumField + NumEq {}


/// Hack needed to use the `Real` type alias.
impl<T: Float + NumField + NumEq> Real for T {}


///
/// Complex numbers (with real components) form a numeric additive
/// magma.
///
impl<T: Real> NumAddMagma for Complex<T> {

  /// Addition is just complex addition.
  fn add(&self, other: &Self) -> Self {
    <Self as Add>::add(*self, *other)
  }
}


///
/// Complex numbers (with real components) form a numeric additive
/// semigroup.
///
impl<T: Real> NumAddSemigroup for Complex<T> {}


///
/// Complex numbers (with real components) form a numeric additive
/// monoid.
///
impl<T: Real> NumAddMonoid for Complex<T> {

  /// Zero is just complex _0 + 0i_.
  fn zero() -> Self {
    Self::new(Zero::zero(), Zero::zero())
  }
}


///
/// Complex numbers (with real components) form a numeric additive
/// group.
///
impl<T: Real> NumAddGroup for Complex<T> {

  /// Negation is just complex negation.
  fn negate(&self) -> Self {
    <Self as Neg>::neg(*self)
  }
}


///
/// Complex numbers (with real components) form a numeric additive
/// commutative group.
///
impl<T: Real> NumAddComGroup for Complex<T> {}


///
/// Complex numbers (with real components) form a numeric
/// multiplicative magma.
///
impl<T: Real> NumMulMagma for Complex<T> {

  /// Multiplication is just complex multiplication.
  fn mul(&self, other: &Self) -> Self {
    <Self as Mul>::mul(*self, *other)
  }
}


///
/// Complex numbers (with real components) form a numeric
/// multiplicative semigroup.
///
impl<T: Real> NumMulSemigroup for Complex<T> {}


///
/// Complex numbers (with real components) form a numeric
/// multiplicative monoid.
///
impl<T: Real> NumMulMonoid for Complex<T> {

  /// One is just complex _1 + 0i_.
  fn one() -> Self {
    Self::new(One::one(), Zero::zero())
  }
}


///
/// Non-zero complex numbers (with real components) form a
/// numeric multiplicative group.
///
impl<T: Real> NumMulGroup for Complex<T> {

  /// Inversion is just complex inversion.
  fn invert(&self) -> Self {
    self.inv()
  }


  /// Non-zero complex numbers are invertible.
  fn is_invertible(&self) -> bool {
    *self != Self::new(Zero::zero(), Zero::zero())
  }
}


///
/// Non-zero complex numbers (with real components) form a
/// numeric multiplicative commutative group.
///
impl<T: Real> NumMulComGroup for Complex<T> {}


///
/// Complex numbers (with real components) form a numeric ring.
///
impl<T: Real> NumRing for Complex<T> {}


///
/// Complex numbers (with real components) form a numeric commutative
/// ring.
///
impl<T: Real> NumComRing for Complex<T> {}


///
/// Non-zero Complex numbers (with real components) form a numeric
/// field.
///
impl<T: Real> NumField for Complex<T> {

  /// Inversion is just complex inversion.
  fn invert(&self) -> Self {
    self.inv()
  }

  
  /// Non-zero complex numbers are invertible.
  fn is_invertible(&self) -> bool {
    *self != Self::new(Zero::zero(), Zero::zero())
  }
}


// Module unit tests are in a separate file.
#[cfg(test)]
#[path = "complex_test.rs"]
mod complex_test;