peroxide/traits/
math.rs

1use crate::structure::matrix::Matrix;
2
3/// Mathematical Vector
4///
5/// # Description
6/// Vector has two operations : addition, scalar multiplication.
7/// And a space of the vector should closed for that operations.
8pub trait Vector {
9    type Scalar;
10    fn add_vec(&self, rhs: &Self) -> Self;
11    fn sub_vec(&self, rhs: &Self) -> Self;
12    fn mul_scalar(&self, rhs: Self::Scalar) -> Self;
13}
14
15/// Kinds of Vector & Matrix norm
16///
17/// # Kinds of Vector norm
18/// * `l1`
19/// * `l2`
20/// * `lp`
21/// * `lInf`
22///
23/// # Kinds of Matrix norm
24/// * `F`: Frobenius norm
25/// * `lpq`: Element-wise pq norm
26#[derive(Debug, Copy, Clone)]
27pub enum Norm {
28    L1,
29    L2,
30    Lp(f64),
31    LInf,
32    F,
33    Lpq(f64, f64),
34}
35
36/// Normed Vector
37pub trait Normed: Vector {
38    type UnsignedScalar;
39    fn norm(&self, kind: Norm) -> Self::UnsignedScalar;
40    fn normalize(&self, kind: Norm) -> Self
41    where
42        Self: Sized;
43}
44
45/// Inner product Vector
46pub trait InnerProduct: Normed {
47    fn dot(&self, rhs: &Self) -> Self::Scalar;
48}
49
50/// Linear operation for Vector
51pub trait LinearOp<T: Vector, S: Vector> {
52    fn apply(&self, rhs: &T) -> S;
53}
54
55/// Vector Products
56pub trait VectorProduct: Vector {
57    fn cross(&self, other: &Self) -> Self;
58    fn outer(&self, other: &Self) -> Matrix;
59}
60
61/// Matrix Products
62pub trait MatrixProduct {
63    fn kronecker(&self, other: &Self) -> Self;
64    fn hadamard(&self, other: &Self) -> Self;
65}
66
67// =============================================================================
68// Implementation for primitive types
69// =============================================================================
70
71impl Vector for f64 {
72    type Scalar = Self;
73
74    fn add_vec(&self, rhs: &Self) -> Self {
75        self + rhs
76    }
77
78    fn sub_vec(&self, rhs: &Self) -> Self {
79        self - rhs
80    }
81
82    fn mul_scalar(&self, rhs: Self::Scalar) -> Self {
83        self * rhs
84    }
85}
86
87impl Normed for f64 {
88    type UnsignedScalar = f64;
89    fn norm(&self, _kind: Norm) -> Self::Scalar {
90        self.abs()
91    }
92
93    fn normalize(&self, _kind: Norm) -> Self
94    where
95        Self: Sized,
96    {
97        self / self.abs()
98    }
99}
100
101// =============================================================================
102// Implementation for parallel traits
103// =============================================================================
104
105/// Mathematical Vector in Parallel
106#[cfg(feature = "parallel")]
107pub trait ParallelVector {
108    type Scalar;
109    fn par_add_vec(&self, rhs: &Self) -> Self;
110    fn par_sub_vec(&self, rhs: &Self) -> Self;
111    fn par_mul_scalar(&self, rhs: Self::Scalar) -> Self;
112}
113
114/// Normed Vector in Parallel
115#[cfg(feature = "parallel")]
116pub trait ParallelNormed: Vector {
117    type UnsignedScalar;
118    fn par_norm(&self, kind: Norm) -> Self::UnsignedScalar;
119}
120
121/// Inner product Vector in Parallel
122#[cfg(feature = "parallel")]
123pub trait ParallelInnerProduct: ParallelNormed {
124    fn par_dot(&self, rhs: &Self) -> Self::Scalar;
125}
126
127/// Matrix Products in Parallel
128#[cfg(feature = "parallel")]
129pub trait ParallelMatrixProduct {
130    fn par_hadamard(&self, other: &Self) -> Self;
131}
132
133/// Vector Products in Parallel
134#[cfg(feature = "parallel")]
135pub trait ParallelVectorProduct: Vector {
136    fn par_cross(&self, other: &Self) -> Self;
137}