use crate::Rational;
use crate::gaussian_rational::GaussianRational;
use core::mem::take;
use malachite_base::num::arithmetic::traits::{Square, SquareAssign};
use malachite_base::num::basic::traits::Zero;
fn square_val(x: GaussianRational) -> GaussianRational {
if x.imaginary == 0u32 {
return GaussianRational {
real: x.real.square(),
imaginary: Rational::ZERO,
};
}
if x.real == 0u32 {
return GaussianRational {
real: -x.imaginary.square(),
imaginary: Rational::ZERO,
};
}
let real = (&x.real).square() - (&x.imaginary).square();
GaussianRational {
real,
imaginary: (x.real * x.imaginary) << 1u32,
}
}
fn square_ref(x: &GaussianRational) -> GaussianRational {
if x.imaginary == 0u32 {
return GaussianRational {
real: (&x.real).square(),
imaginary: Rational::ZERO,
};
}
if x.real == 0u32 {
return GaussianRational {
real: -(&x.imaginary).square(),
imaginary: Rational::ZERO,
};
}
GaussianRational {
real: (&x.real).square() - (&x.imaginary).square(),
imaginary: (&x.real * &x.imaginary) << 1u32,
}
}
impl Square for GaussianRational {
type Output = Self;
#[inline]
fn square(self) -> Self {
square_val(self)
}
}
impl Square for &GaussianRational {
type Output = GaussianRational;
#[inline]
fn square(self) -> GaussianRational {
square_ref(self)
}
}
impl SquareAssign for GaussianRational {
#[inline]
fn square_assign(&mut self) {
*self = square_val(take(self));
}
}