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