use std::ops::{Mul, MulAssign, Div, DivAssign}; use alga::general::Real; use core::{Unit, ColumnVector, OwnedColumnVector}; use core::dimension::{U1, U2}; use core::storage::Storage; use geometry::{UnitComplex, RotationBase, PointBase, OwnedPoint}; /* * This file provides: * =================== * * UnitComplex × UnitComplex * UnitComplex × RotationBase -> UnitComplex * RotationBase × UnitComplex -> UnitComplex * * UnitComplex ÷ UnitComplex * UnitComplex ÷ RotationBase -> UnitComplex * RotationBase ÷ UnitComplex -> UnitComplex * * * UnitComplex × PointBase * UnitComplex × ColumnVector * UnitComplex × Unit * * NOTE: -UnitComplex is already provided by `Unit`. * * * (Assignment Operators) * * UnitComplex ×= UnitComplex * UnitComplex ×= RotationBase * * UnitComplex ÷= UnitComplex * UnitComplex ÷= RotationBase * * FIXME: RotationBase ×= UnitComplex * FIXME: RotationBase ÷= UnitComplex * */ // UnitComplex × UnitComplex impl Mul> for UnitComplex { type Output = UnitComplex; #[inline] fn mul(self, rhs: UnitComplex) -> UnitComplex { Unit::new_unchecked(self.unwrap() * rhs.unwrap()) } } impl<'a, N: Real> Mul> for &'a UnitComplex { type Output = UnitComplex; #[inline] fn mul(self, rhs: UnitComplex) -> UnitComplex { Unit::new_unchecked(self.complex() * rhs.unwrap()) } } impl<'b, N: Real> Mul<&'b UnitComplex> for UnitComplex { type Output = UnitComplex; #[inline] fn mul(self, rhs: &'b UnitComplex) -> UnitComplex { Unit::new_unchecked(self.unwrap() * rhs.complex()) } } impl<'a, 'b, N: Real> Mul<&'b UnitComplex> for &'a UnitComplex { type Output = UnitComplex; #[inline] fn mul(self, rhs: &'b UnitComplex) -> UnitComplex { Unit::new_unchecked(self.complex() * rhs.complex()) } } // UnitComplex ÷ UnitComplex impl Div> for UnitComplex { type Output = UnitComplex; #[inline] fn div(self, rhs: UnitComplex) -> UnitComplex { Unit::new_unchecked(self.unwrap() * rhs.conjugate().unwrap()) } } impl<'a, N: Real> Div> for &'a UnitComplex { type Output = UnitComplex; #[inline] fn div(self, rhs: UnitComplex) -> UnitComplex { Unit::new_unchecked(self.complex() * rhs.conjugate().unwrap()) } } impl<'b, N: Real> Div<&'b UnitComplex> for UnitComplex { type Output = UnitComplex; #[inline] fn div(self, rhs: &'b UnitComplex) -> UnitComplex { Unit::new_unchecked(self.unwrap() * rhs.conjugate().unwrap()) } } impl<'a, 'b, N: Real> Div<&'b UnitComplex> for &'a UnitComplex { type Output = UnitComplex; #[inline] fn div(self, rhs: &'b UnitComplex) -> UnitComplex { Unit::new_unchecked(self.complex() * rhs.conjugate().unwrap()) } } macro_rules! complex_op_impl( ($Op: ident, $op: ident; ($RDim: ident, $CDim: ident); $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $action: expr; $($lives: tt),*) => { impl<$($lives ,)* N, S> $Op<$Rhs> for $Lhs where N: Real, S: Storage { type Output = $Result; #[inline] fn $op($lhs, $rhs: $Rhs) -> Self::Output { $action } } } ); macro_rules! complex_op_impl_all( ($Op: ident, $op: ident; ($RDim: ident, $CDim: ident); $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; [val val] => $action_val_val: expr; [ref val] => $action_ref_val: expr; [val ref] => $action_val_ref: expr; [ref ref] => $action_ref_ref: expr;) => { complex_op_impl!($Op, $op; ($RDim, $CDim); $lhs: $Lhs, $rhs: $Rhs, Output = $Result; $action_val_val; ); complex_op_impl!($Op, $op; ($RDim, $CDim); $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result; $action_ref_val; 'a); complex_op_impl!($Op, $op; ($RDim, $CDim); $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result; $action_val_ref; 'b); complex_op_impl!($Op, $op; ($RDim, $CDim); $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result; $action_ref_ref; 'a, 'b); } ); // UnitComplex × RotationBase complex_op_impl_all!( Mul, mul; (U2, U2); self: UnitComplex, rhs: RotationBase, Output = UnitComplex; [val val] => &self * &rhs; [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => self * UnitComplex::from_rotation_matrix(rhs); ); // UnitComplex ÷ RotationBase complex_op_impl_all!( Div, div; (U2, U2); self: UnitComplex, rhs: RotationBase, Output = UnitComplex; [val val] => &self / &rhs; [ref val] => self / &rhs; [val ref] => &self / rhs; [ref ref] => self * UnitComplex::from_rotation_matrix(rhs).inverse(); ); // RotationBase × UnitComplex complex_op_impl_all!( Mul, mul; (U2, U2); self: RotationBase, rhs: UnitComplex, Output = UnitComplex; [val val] => &self * &rhs; [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => UnitComplex::from_rotation_matrix(self) * rhs; ); // RotationBase ÷ UnitComplex complex_op_impl_all!( Div, div; (U2, U2); self: RotationBase, rhs: UnitComplex, Output = UnitComplex; [val val] => &self / &rhs; [ref val] => self / &rhs; [val ref] => &self / rhs; [ref ref] => UnitComplex::from_rotation_matrix(self) * rhs.inverse(); ); // UnitComplex × PointBase complex_op_impl_all!( Mul, mul; (U2, U1); self: UnitComplex, rhs: PointBase, Output = OwnedPoint; [val val] => &self * &rhs; [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => PointBase::from_coordinates(self * &rhs.coords); ); // UnitComplex × ColumnVector complex_op_impl_all!( Mul, mul; (U2, U1); self: UnitComplex, rhs: ColumnVector, Output = OwnedColumnVector; [val val] => &self * &rhs; [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => { let i = self.as_ref().im; let r = self.as_ref().re; OwnedColumnVector::<_, U2, S::Alloc>::new(r * rhs[0] - i * rhs[0], i * rhs[1] + r * rhs[1]) }; ); // UnitComplex × Unit complex_op_impl_all!( Mul, mul; (U2, U1); self: UnitComplex, rhs: Unit>, Output = Unit>; [val val] => &self * &rhs; [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => Unit::new_unchecked(self * rhs.as_ref()); ); // UnitComplex ×= UnitComplex impl MulAssign> for UnitComplex { #[inline] fn mul_assign(&mut self, rhs: UnitComplex) { *self = &*self * rhs } } impl<'b, N: Real> MulAssign<&'b UnitComplex> for UnitComplex { #[inline] fn mul_assign(&mut self, rhs: &'b UnitComplex) { *self = &*self * rhs } } // UnitComplex /= UnitComplex impl DivAssign> for UnitComplex { #[inline] fn div_assign(&mut self, rhs: UnitComplex) { *self = &*self / rhs } } impl<'b, N: Real> DivAssign<&'b UnitComplex> for UnitComplex { #[inline] fn div_assign(&mut self, rhs: &'b UnitComplex) { *self = &*self / rhs } } // UnitComplex ×= RotationBase impl> MulAssign> for UnitComplex { #[inline] fn mul_assign(&mut self, rhs: RotationBase) { *self = &*self * rhs } } impl<'b, N: Real, S: Storage> MulAssign<&'b RotationBase> for UnitComplex { #[inline] fn mul_assign(&mut self, rhs: &'b RotationBase) { *self = &*self * rhs } } // UnitComplex ÷= RotationBase impl> DivAssign> for UnitComplex { #[inline] fn div_assign(&mut self, rhs: RotationBase) { *self = &*self / rhs } } impl<'b, N: Real, S: Storage> DivAssign<&'b RotationBase> for UnitComplex { #[inline] fn div_assign(&mut self, rhs: &'b RotationBase) { *self = &*self / rhs } }