pub mod angle;
pub mod z;
use angle::*;
use std::fmt;
use z::*;
#[derive(Debug)]
pub struct Angle {
pub d: Degree,
pub r: Radian,
}
impl Angle {
pub fn from_degrees(d: f64) -> Angle {
let d = Degree::from(d);
let r = d.to_radians();
Angle { d, r }
}
pub fn from_radians(r: f64) -> Angle {
let r = Radian::from(r);
let d = r.to_degrees();
Angle { d, r }
}
}
impl Clone for Angle {
fn clone(&self) -> Angle {
Angle::from_degrees(self.d.value)
}
}
#[derive(Debug)]
pub struct ComplexNumber {
cartesian: CartesianComplexNumber,
polar: PolarComplexNumber,
}
impl ComplexNumber {
pub fn from_cartesian(real: f64, imaginary: f64) -> ComplexNumber {
let cartesian = CartesianComplexNumber { real, imaginary };
let polar = cartesian.to_polar();
ComplexNumber { cartesian, polar }
}
pub fn from_polar(magnitude: f64, angle: Angle) -> ComplexNumber {
let polar = PolarComplexNumber { magnitude, angle };
let cartesian = polar.to_cartesian();
ComplexNumber { cartesian, polar }
}
pub fn from_real(real: f64) -> ComplexNumber {
ComplexNumber::from_cartesian(real, 0.0)
}
pub fn abs(&self) -> f64 {
self.polar.magnitude
}
pub fn angle_in_rads(&self) -> f64 {
round_five_zeros(self.polar.angle.r.value)
}
pub fn angle_in_degs(&self) -> f64 {
round_three_zeros(self.polar.angle.d.value)
}
pub fn angle_in_angle(&self) -> Angle {
self.polar.angle.clone()
}
pub fn real(&self) -> f64 {
self.cartesian.real
}
pub fn imag(&self) -> f64 {
self.cartesian.imaginary
}
pub fn add(&self, z2: &ComplexNumber) -> ComplexNumber {
let real = self.real() + z2.real();
let imaginary = self.imag() + z2.imag();
ComplexNumber::from_cartesian(real, imaginary)
}
pub fn sub(&self, z2: &ComplexNumber) -> ComplexNumber {
let real = self.real() - z2.real();
let imaginary = self.imag() - z2.imag();
ComplexNumber::from_cartesian(real, imaginary)
}
pub fn mul(&self, z2: &ComplexNumber) -> ComplexNumber {
let magnitude = self.abs() * z2.abs();
let angle = Angle::from_radians(self.angle_in_rads() + z2.angle_in_rads());
ComplexNumber::from_polar(magnitude, angle)
}
pub fn mul_n(&self, n: f64) -> ComplexNumber {
let magnitude = self.abs() * n;
ComplexNumber::from_polar(magnitude, self.angle_in_angle())
}
pub fn div(&self, z2: &ComplexNumber) -> ComplexNumber {
let magnitude = self.abs() / z2.abs();
let angle = Angle::from_radians(self.angle_in_rads() - z2.angle_in_rads());
ComplexNumber::from_polar(magnitude, angle)
}
pub fn pow(&self, n: f64) -> ComplexNumber {
let magnitude = self.abs().powf(n);
let angle = Angle::from_radians(self.angle_in_rads() * n);
ComplexNumber::from_polar(magnitude, angle)
}
pub fn nth_root(&self, n: f64) -> ComplexNumber {
let magnitude: f64 = self.abs().powf(1.0 / n);
let angle = Angle::from_radians(self.angle_in_rads() / n);
ComplexNumber::from_polar(magnitude, angle)
}
pub fn ln(&self) -> ComplexNumber {
let magnitude = self.abs().ln();
ComplexNumber::from_polar(magnitude, self.angle_in_angle())
}
pub fn log10(&self) -> ComplexNumber {
let magnitude = self.abs().log10();
ComplexNumber::from_polar(magnitude, self.angle_in_angle())
}
pub fn log(&self, arb: f64) -> ComplexNumber {
let magnitude = self.abs().log(arb);
ComplexNumber::from_polar(magnitude, self.angle_in_angle())
}
pub fn print_cartesian(&self) {
print!("cartesian form: {} + {} j", self.real(), self.imag());
}
pub fn print_polar(&self) {
println!(
"polar form (radian): {} e ^ {} ㎭ j",
self.abs(),
self.angle_in_rads()
);
println!(
"polar form (degree): {} e ^ {}° j",
self.abs(),
self.angle_in_degs()
);
}
}
impl fmt::Display for ComplexNumber {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mag_as_sqrt = self.polar.magnitude.powi(2);
writeln!(
f,
"
Pretty Values:
Cartesian Form (Pretty): {:.1} + {:.1} j
Polar Form (Pretty): √{:.0} e ^ {:.1}㎭ j
Polar Form (Pretty): √{:.0} e ^ {:.1}° j
Precision Values:
Cartesian Form (Pretty): {} + {} j
Polar Form (Pretty): {} e ^ {}㎭ j
Polar Form (Pretty): {} e ^ {}° j ",
self.cartesian.real,
self.cartesian.imaginary,
mag_as_sqrt,
self.polar.angle.r.value,
mag_as_sqrt,
self.polar.angle.d.value,
self.cartesian.real,
self.cartesian.imaginary,
self.polar.magnitude,
self.polar.angle.r.value,
self.polar.magnitude,
self.polar.angle.d.value,
)
}
}
impl PartialEq for ComplexNumber {
fn eq(&self, other: &Self) -> bool {
let c1 = round_five_zeros(self.abs()) == round_five_zeros(other.abs());
let c2 = round_five_zeros(self.angle_in_degs()) == round_five_zeros(other.angle_in_degs());
let c3 = round_five_zeros(self.angle_in_rads()) == round_five_zeros(other.angle_in_rads());
let c4 = round_five_zeros(self.imag()) == round_five_zeros(other.imag());
let c5 = round_five_zeros(self.real()) == round_five_zeros(other.real());
c1 && c2 && c3 && c4 && c5
}
}
fn round_five_zeros(n: f64) -> f64 {
let five_zeros = 1_00000_f64;
(n * five_zeros).round() / five_zeros
}
fn round_three_zeros(n: f64) -> f64 {
let three_zeros = 1_000_f64;
(n * three_zeros).round() / three_zeros
}