vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use crate::operators::*;
use std::ops::{Add, Sub, Mul, Div};

/// # VectorExpression

///
/// # Base class for vector expression.
///
/// Vector expression is a meta type that enables template expression pattern.
///
/// - tparam T - Real number type.
/// - tparam E - Subclass type.
///
pub trait VectorExpression {
    fn size(&self) -> usize;

    fn eval(&self, i: usize) -> f64;
}

/// # VectorUnaryOp

///
/// # Vector expression for unary operation.
///
/// This matrix expression represents an unary vector operation that takes
/// single input vector expression.
///
/// - tparam T - Real number type.
/// - tparam E - Input expression type.
/// - tparam Op - Unary operation.
///
pub struct VectorUnaryOp<E: VectorExpression, Op: UnaryOp> {
    _u: E,
    _op: Op,
}

impl<E: VectorExpression, Op: UnaryOp> VectorUnaryOp<E, Op> {
    /// Constructs unary operation expression for given input expression.
    pub fn new(u: E) -> VectorUnaryOp<E, Op> {
        return VectorUnaryOp {
            _u: u,
            _op: Op::new(),
        };
    }
}

impl<E: VectorExpression, Op: UnaryOp> VectorExpression for VectorUnaryOp<E, Op> {
    /// Size of the vector.
    fn size(&self) -> usize {
        return self._u.size();
    }

    /// Returns vector element at i.
    fn eval(&self, i: usize) -> f64 {
        return self._op.eval(self._u.eval(i));
    }
}

//--------------------------------------------------------------------------------------------------
/// # VectorBinaryOp

///
/// \brief Vector expression for binary operation.
///
/// This vector expression represents a binary vector operation that takes
/// two input vector expressions.
///
/// - tparam T - Real number type.
/// - tparam E1 - First input expression type.
/// - tparam E2 - Second input expression type.
/// - tparam Op - Binary operation.
///
pub struct VectorBinaryOp<E1: VectorExpression, E2: VectorExpression, Op: BinaryOp> {
    _u: E1,
    _v: E2,
    _op: Op,
}

impl<E1: VectorExpression, E2: VectorExpression, Op: BinaryOp> VectorBinaryOp<E1, E2, Op> {
    /// Constructs binary operation expression for given input vector
    /// expressions.
    pub fn new(u: E1, v: E2) -> VectorBinaryOp<E1, E2, Op> {
        return VectorBinaryOp {
            _u: u,
            _v: v,
            _op: Op::new(),
        };
    }
}

impl<E1: VectorExpression, E2: VectorExpression, Op: BinaryOp> VectorExpression for VectorBinaryOp<E1, E2, Op> {
    /// Size of the Vector.
    fn size(&self) -> usize {
        return self._v.size();
    }

    /// Returns vector element at i.
    fn eval(&self, i: usize) -> f64 {
        return self._op.eval(self._u.eval(i), self._v.eval(i));
    }
}

//--------------------------------------------------------------------------------------------------
///
/// # Vector expression for matrix-scalar binary operation.
///
/// This vector expression represents a binary matrix operation that takes
/// one input vector expression and one scalar.
///
/// - tparam T - Real number type.
/// - tparam E - Input expression type.
/// - tparam Op - Binary operation.
///
pub struct VectorScalarBinaryOp<E: VectorExpression, Op: BinaryOp> {
    _u: E,
    _v: f64,
    _op: Op,
}

impl<E: VectorExpression, Op: BinaryOp> VectorScalarBinaryOp<E, Op> {
    /// Constructs a binary expression for given vector and scalar.
    pub fn new(u: E, v: f64) -> VectorScalarBinaryOp<E, Op> {
        return VectorScalarBinaryOp {
            _u: u,
            _v: v,
            _op: Op::new(),
        };
    }
}

impl<E: VectorExpression, Op: BinaryOp> VectorExpression for VectorScalarBinaryOp<E, Op> {
    fn size(&self) -> usize {
        return self._u.size();
    }

    fn eval(&self, i: usize) -> f64 {
        return self._op.eval(self._u.eval(i), self._v);
    }
}

//--------------------------------------------------------------------------------------------------
/// # VectorBinaryOp Aliases
/// Vector-vector addition expression.
pub type VectorAdd<E1, E2> = VectorBinaryOp<E1, E2, Plus>;

/// Vector-scalar addition expression.
pub type VectorScalarAdd<E> = VectorScalarBinaryOp<E, Plus>;

/// Vector-vector addition expression.
pub type VectorSub<E1, E2> = VectorBinaryOp<E1, E2, Minus>;

/// Vector-scalar subtraction expression.
pub type VectorScalarSub<E> = VectorScalarBinaryOp<E, Minus>;

/// Scalar-vector subtraction expression.
pub type VectorScalarRSub<E> = VectorScalarBinaryOp<E, RMinus>;

/// Element-wise vector-vector multiplication expression.
pub type VectorMul<E1, E2> = VectorBinaryOp<E1, E2, Multiplies>;

/// Vector-scalar multiplication expression.
pub type VectorScalarMul<E> = VectorScalarBinaryOp<E, Multiplies>;

/// Element-wise vector-vector division expression.
pub type VectorDiv<E1, E2> = VectorBinaryOp<E1, E2, Divides>;

/// Vector-scalar division expression.
pub type VectorScalarDiv<E> = VectorScalarBinaryOp<E, Divides>;

/// Scalar-vector division expression.
pub type VectorScalarRDiv<E> = VectorScalarBinaryOp<E, RDivides>;

//--------------------------------------------------------------------------------------------------
/// # Global Functions
macro_rules! impl_vec1 {
    ($Vector:ty) => {
        /// Vector-scalar addition operation.
        impl<E1: VectorExpression> Add<f64> for $Vector {
            type Output = VectorScalarAdd<$Vector>;

            fn add(self, rhs: f64) -> Self::Output {
                return VectorScalarAdd::new(self, rhs);
            }
        }

        /// Vector-vector addition operation.
        impl<Return: VectorExpression, E1: VectorExpression> Add<Return> for $Vector {
            type Output = VectorAdd<$Vector, Return>;

            fn add(self, rhs: Return) -> Self::Output {
                return VectorAdd::new(self, rhs);
            }
        }

        /// Scalar-vector subtraction operation.
        impl<E1: VectorExpression> Sub<f64> for $Vector {
            type Output = VectorScalarSub<$Vector>;

            fn sub(self, rhs: f64) -> Self::Output {
                return VectorScalarSub::new(self, rhs);
            }
        }

        /// Vector-vector subtraction operation.
        impl<Return: VectorExpression, E1: VectorExpression> Sub<Return> for $Vector {
            type Output = VectorSub<$Vector, Return>;

            fn sub(self, rhs: Return) -> Self::Output {
                return VectorSub::new(self, rhs);
            }
        }

        /// Vector-scalar multiplication operation.
        impl<E1: VectorExpression> Mul<f64> for $Vector {
            type Output = VectorScalarMul<$Vector>;

            fn mul(self, rhs: f64) -> Self::Output {
                return VectorScalarMul::new(self, rhs);
            }
        }

        /// Element-wise vector-vector multiplication operation.
        impl<Return: VectorExpression, E1: VectorExpression> Mul<Return> for $Vector {
            type Output = VectorMul<$Vector, Return>;

            fn mul(self, rhs: Return) -> Self::Output {
                return VectorMul::new(self, rhs);
            }
        }

        /// Vector-scalar division operation.
        impl<E1: VectorExpression> Div<f64> for $Vector {
            type Output = VectorScalarDiv<$Vector>;

            fn div(self, rhs: f64) -> Self::Output {
                return VectorScalarDiv::new(self, rhs);
            }
        }

        /// Element-wise vector-vector division operation.
        impl<Return: VectorExpression, E1: VectorExpression> Div<Return> for $Vector {
            type Output = VectorDiv<$Vector, Return>;

            fn div(self, rhs: Return) -> Self::Output {
                return VectorDiv::new(self, rhs);
            }
        }
    }
}
impl_vec1!(VectorScalarAdd<E1>);
impl_vec1!(VectorScalarSub<E1>);
impl_vec1!(VectorScalarRSub<E1>);
impl_vec1!(VectorScalarMul<E1>);
impl_vec1!(VectorScalarDiv<E1>);
impl_vec1!(VectorScalarRDiv<E1>);

macro_rules! impl_vec2 {
    ($Vector:ty) => {
        /// Vector-scalar addition operation.
        impl<E1: VectorExpression, E2: VectorExpression> Add<f64> for $Vector {
            type Output = VectorScalarAdd<$Vector>;

            fn add(self, rhs: f64) -> Self::Output {
                return VectorScalarAdd::new(self, rhs);
            }
        }

        /// Vector-vector addition operation.
        impl<Return: VectorExpression, E1: VectorExpression, E2: VectorExpression> Add<Return> for $Vector {
            type Output = VectorAdd<$Vector, Return>;

            fn add(self, rhs: Return) -> Self::Output {
                return VectorAdd::new(self, rhs);
            }
        }

        /// Scalar-vector subtraction operation.
        impl<E1: VectorExpression, E2: VectorExpression> Sub<f64> for $Vector {
            type Output = VectorScalarSub<$Vector>;

            fn sub(self, rhs: f64) -> Self::Output {
                return VectorScalarSub::new(self, rhs);
            }
        }

        /// Vector-vector subtraction operation.
        impl<Return: VectorExpression, E1: VectorExpression, E2: VectorExpression> Sub<Return> for $Vector {
            type Output = VectorSub<$Vector, Return>;

            fn sub(self, rhs: Return) -> Self::Output {
                return VectorSub::new(self, rhs);
            }
        }

        /// Vector-scalar multiplication operation.
        impl<E1: VectorExpression, E2: VectorExpression> Mul<f64> for $Vector {
            type Output = VectorScalarMul<$Vector>;

            fn mul(self, rhs: f64) -> Self::Output {
                return VectorScalarMul::new(self, rhs);
            }
        }

        /// Element-wise vector-vector multiplication operation.
        impl<Return: VectorExpression, E1: VectorExpression, E2: VectorExpression> Mul<Return> for $Vector {
            type Output = VectorMul<$Vector, Return>;

            fn mul(self, rhs: Return) -> Self::Output {
                return VectorMul::new(self, rhs);
            }
        }

        /// Vector-scalar division operation.
        impl<E1: VectorExpression, E2: VectorExpression> Div<f64> for $Vector {
            type Output = VectorScalarDiv<$Vector>;

            fn div(self, rhs: f64) -> Self::Output {
                return VectorScalarDiv::new(self, rhs);
            }
        }

        /// Element-wise vector-vector division operation.
        impl<Return: VectorExpression, E1: VectorExpression, E2: VectorExpression> Div<Return> for $Vector {
            type Output = VectorDiv<$Vector, Return>;

            fn div(self, rhs: Return) -> Self::Output {
                return VectorDiv::new(self, rhs);
            }
        }
    }
}
impl_vec2!(VectorAdd<E1, E2>);
impl_vec2!(VectorSub<E1, E2>);
impl_vec2!(VectorMul<E1, E2>);
impl_vec2!(VectorDiv<E1, E2>);