feat: adds 3 more SVM kernels, linalg refactoring
This commit is contained in:
@@ -91,6 +91,76 @@ pub trait BaseVector<T: RealNumber>: Clone + Debug {
|
||||
|
||||
/// Returns True if matrices are element-wise equal within a tolerance `error`.
|
||||
fn approximate_eq(&self, other: &Self, error: T) -> bool;
|
||||
|
||||
/// Returns [L2 norm] of the vector(https://en.wikipedia.org/wiki/Matrix_norm).
|
||||
fn norm2(&self) -> T;
|
||||
|
||||
/// Returns [vectors norm](https://en.wikipedia.org/wiki/Matrix_norm) of order `p`.
|
||||
fn norm(&self, p: T) -> T;
|
||||
|
||||
/// Divide single element of the vector by `x`, write result to original vector.
|
||||
fn div_element_mut(&mut self, pos: usize, x: T);
|
||||
|
||||
/// Multiply single element of the vector by `x`, write result to original vector.
|
||||
fn mul_element_mut(&mut self, pos: usize, x: T);
|
||||
|
||||
/// Add single element of the vector to `x`, write result to original vector.
|
||||
fn add_element_mut(&mut self, pos: usize, x: T);
|
||||
|
||||
/// Subtract `x` from single element of the vector, write result to original vector.
|
||||
fn sub_element_mut(&mut self, pos: usize, x: T);
|
||||
|
||||
/// Add vectors, element-wise, overriding original vector with result.
|
||||
fn add_mut(&mut self, other: &Self) -> &Self;
|
||||
|
||||
/// Subtract vectors, element-wise, overriding original vector with result.
|
||||
fn sub_mut(&mut self, other: &Self) -> &Self;
|
||||
|
||||
/// Multiply vectors, element-wise, overriding original vector with result.
|
||||
fn mul_mut(&mut self, other: &Self) -> &Self;
|
||||
|
||||
/// Divide vectors, element-wise, overriding original vector with result.
|
||||
fn div_mut(&mut self, other: &Self) -> &Self;
|
||||
|
||||
/// Add vectors, element-wise
|
||||
fn add(&self, other: &Self) -> Self {
|
||||
let mut r = self.clone();
|
||||
r.add_mut(other);
|
||||
r
|
||||
}
|
||||
|
||||
/// Subtract vectors, element-wise
|
||||
fn sub(&self, other: &Self) -> Self {
|
||||
let mut r = self.clone();
|
||||
r.sub_mut(other);
|
||||
r
|
||||
}
|
||||
|
||||
/// Multiply vectors, element-wise
|
||||
fn mul(&self, other: &Self) -> Self {
|
||||
let mut r = self.clone();
|
||||
r.mul_mut(other);
|
||||
r
|
||||
}
|
||||
|
||||
/// Divide vectors, element-wise
|
||||
fn div(&self, other: &Self) -> Self {
|
||||
let mut r = self.clone();
|
||||
r.div_mut(other);
|
||||
r
|
||||
}
|
||||
|
||||
/// Calculates sum of all elements of the vector.
|
||||
fn sum(&self) -> T;
|
||||
|
||||
/// Returns unique values from the vector.
|
||||
/// ```
|
||||
/// use smartcore::linalg::naive::dense_matrix::*;
|
||||
/// let a = vec!(1., 2., 2., -2., -6., -7., 2., 3., 4.);
|
||||
///
|
||||
///assert_eq!(a.unique(), vec![-7., -6., -2., 1., 2., 3., 4.]);
|
||||
/// ```
|
||||
fn unique(&self) -> Vec<T>;
|
||||
}
|
||||
|
||||
/// Generic matrix type.
|
||||
|
||||
@@ -58,6 +58,96 @@ impl<T: RealNumber> BaseVector<T> for Vec<T> {
|
||||
result
|
||||
}
|
||||
|
||||
fn norm2(&self) -> T {
|
||||
let mut norm = T::zero();
|
||||
|
||||
for xi in self.iter() {
|
||||
norm = norm + *xi * *xi;
|
||||
}
|
||||
|
||||
norm.sqrt()
|
||||
}
|
||||
|
||||
fn norm(&self, p: T) -> T {
|
||||
if p.is_infinite() && p.is_sign_positive() {
|
||||
self.iter()
|
||||
.map(|x| x.abs())
|
||||
.fold(T::neg_infinity(), |a, b| a.max(b))
|
||||
} else if p.is_infinite() && p.is_sign_negative() {
|
||||
self.iter()
|
||||
.map(|x| x.abs())
|
||||
.fold(T::infinity(), |a, b| a.min(b))
|
||||
} else {
|
||||
let mut norm = T::zero();
|
||||
|
||||
for xi in self.iter() {
|
||||
norm = norm + xi.abs().powf(p);
|
||||
}
|
||||
|
||||
norm.powf(T::one() / p)
|
||||
}
|
||||
}
|
||||
|
||||
fn div_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] / x;
|
||||
}
|
||||
|
||||
fn mul_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] * x;
|
||||
}
|
||||
|
||||
fn add_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] + x
|
||||
}
|
||||
|
||||
fn sub_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] - x;
|
||||
}
|
||||
|
||||
fn add_mut(&mut self, other: &Self) -> &Self {
|
||||
if self.len() != other.len() {
|
||||
panic!("A and B should have the same shape");
|
||||
}
|
||||
for i in 0..self.len() {
|
||||
self.add_element_mut(i, other.get(i));
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn sub_mut(&mut self, other: &Self) -> &Self {
|
||||
if self.len() != other.len() {
|
||||
panic!("A and B should have the same shape");
|
||||
}
|
||||
for i in 0..self.len() {
|
||||
self.sub_element_mut(i, other.get(i));
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn mul_mut(&mut self, other: &Self) -> &Self {
|
||||
if self.len() != other.len() {
|
||||
panic!("A and B should have the same shape");
|
||||
}
|
||||
for i in 0..self.len() {
|
||||
self.mul_element_mut(i, other.get(i));
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn div_mut(&mut self, other: &Self) -> &Self {
|
||||
if self.len() != other.len() {
|
||||
panic!("A and B should have the same shape");
|
||||
}
|
||||
for i in 0..self.len() {
|
||||
self.div_element_mut(i, other.get(i));
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn approximate_eq(&self, other: &Self, error: T) -> bool {
|
||||
if self.len() != other.len() {
|
||||
false
|
||||
@@ -70,6 +160,21 @@ impl<T: RealNumber> BaseVector<T> for Vec<T> {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn sum(&self) -> T {
|
||||
let mut sum = T::zero();
|
||||
for i in 0..self.len() {
|
||||
sum = sum + self[i];
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn unique(&self) -> Vec<T> {
|
||||
let mut result = self.clone();
|
||||
result.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
result.dedup();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// Column-major, dense matrix. See [Simple Dense Matrix](../index.html).
|
||||
|
||||
@@ -84,6 +84,76 @@ impl<T: RealNumber + 'static> BaseVector<T> for MatrixMN<T, U1, Dynamic> {
|
||||
self.dot(other)
|
||||
}
|
||||
|
||||
fn norm2(&self) -> T {
|
||||
self.iter().map(|x| *x * *x).sum::<T>().sqrt()
|
||||
}
|
||||
|
||||
fn norm(&self, p: T) -> T {
|
||||
if p.is_infinite() && p.is_sign_positive() {
|
||||
self.iter().fold(T::neg_infinity(), |f, &val| {
|
||||
let v = val.abs();
|
||||
if f > v {
|
||||
f
|
||||
} else {
|
||||
v
|
||||
}
|
||||
})
|
||||
} else if p.is_infinite() && p.is_sign_negative() {
|
||||
self.iter().fold(T::infinity(), |f, &val| {
|
||||
let v = val.abs();
|
||||
if f < v {
|
||||
f
|
||||
} else {
|
||||
v
|
||||
}
|
||||
})
|
||||
} else {
|
||||
let mut norm = T::zero();
|
||||
|
||||
for xi in self.iter() {
|
||||
norm = norm + xi.abs().powf(p);
|
||||
}
|
||||
|
||||
norm.powf(T::one() / p)
|
||||
}
|
||||
}
|
||||
|
||||
fn div_element_mut(&mut self, pos: usize, x: T) {
|
||||
*self.get_mut(pos).unwrap() = *self.get(pos).unwrap() / x;
|
||||
}
|
||||
|
||||
fn mul_element_mut(&mut self, pos: usize, x: T) {
|
||||
*self.get_mut(pos).unwrap() = *self.get(pos).unwrap() * x;
|
||||
}
|
||||
|
||||
fn add_element_mut(&mut self, pos: usize, x: T) {
|
||||
*self.get_mut(pos).unwrap() = *self.get(pos).unwrap() + x;
|
||||
}
|
||||
|
||||
fn sub_element_mut(&mut self, pos: usize, x: T) {
|
||||
*self.get_mut(pos).unwrap() = *self.get(pos).unwrap() - x;
|
||||
}
|
||||
|
||||
fn add_mut(&mut self, other: &Self) -> &Self {
|
||||
*self += other;
|
||||
self
|
||||
}
|
||||
|
||||
fn sub_mut(&mut self, other: &Self) -> &Self {
|
||||
*self -= other;
|
||||
self
|
||||
}
|
||||
|
||||
fn mul_mut(&mut self, other: &Self) -> &Self {
|
||||
self.component_mul_assign(other);
|
||||
self
|
||||
}
|
||||
|
||||
fn div_mut(&mut self, other: &Self) -> &Self {
|
||||
self.component_div_assign(other);
|
||||
self
|
||||
}
|
||||
|
||||
fn approximate_eq(&self, other: &Self, error: T) -> bool {
|
||||
if self.shape() != other.shape() {
|
||||
false
|
||||
@@ -93,6 +163,21 @@ impl<T: RealNumber + 'static> BaseVector<T> for MatrixMN<T, U1, Dynamic> {
|
||||
.all(|(a, b)| (*a - *b).abs() <= error)
|
||||
}
|
||||
}
|
||||
|
||||
fn sum(&self) -> T {
|
||||
let mut sum = T::zero();
|
||||
for v in self.iter() {
|
||||
sum += *v;
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn unique(&self) -> Vec<T> {
|
||||
let mut result: Vec<T> = self.iter().map(|v| *v).collect();
|
||||
result.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
result.dedup();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealNumber + Scalar + AddAssign + SubAssign + MulAssign + DivAssign + Sum + 'static>
|
||||
|
||||
@@ -89,9 +89,90 @@ impl<T: RealNumber + ScalarOperand> BaseVector<T> for ArrayBase<OwnedRepr<T>, Ix
|
||||
self.dot(other)
|
||||
}
|
||||
|
||||
fn norm2(&self) -> T {
|
||||
self.iter().map(|x| *x * *x).sum::<T>().sqrt()
|
||||
}
|
||||
|
||||
fn norm(&self, p: T) -> T {
|
||||
if p.is_infinite() && p.is_sign_positive() {
|
||||
self.iter().fold(T::neg_infinity(), |f, &val| {
|
||||
let v = val.abs();
|
||||
if f > v {
|
||||
f
|
||||
} else {
|
||||
v
|
||||
}
|
||||
})
|
||||
} else if p.is_infinite() && p.is_sign_negative() {
|
||||
self.iter().fold(T::infinity(), |f, &val| {
|
||||
let v = val.abs();
|
||||
if f < v {
|
||||
f
|
||||
} else {
|
||||
v
|
||||
}
|
||||
})
|
||||
} else {
|
||||
let mut norm = T::zero();
|
||||
|
||||
for xi in self.iter() {
|
||||
norm = norm + xi.abs().powf(p);
|
||||
}
|
||||
|
||||
norm.powf(T::one() / p)
|
||||
}
|
||||
}
|
||||
|
||||
fn div_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] / x;
|
||||
}
|
||||
|
||||
fn mul_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] * x;
|
||||
}
|
||||
|
||||
fn add_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] + x;
|
||||
}
|
||||
|
||||
fn sub_element_mut(&mut self, pos: usize, x: T) {
|
||||
self[pos] = self[pos] - x;
|
||||
}
|
||||
|
||||
fn approximate_eq(&self, other: &Self, error: T) -> bool {
|
||||
(self - other).iter().all(|v| v.abs() <= error)
|
||||
}
|
||||
|
||||
fn add_mut(&mut self, other: &Self) -> &Self {
|
||||
*self += other;
|
||||
self
|
||||
}
|
||||
|
||||
fn sub_mut(&mut self, other: &Self) -> &Self {
|
||||
*self -= other;
|
||||
self
|
||||
}
|
||||
|
||||
fn mul_mut(&mut self, other: &Self) -> &Self {
|
||||
*self *= other;
|
||||
self
|
||||
}
|
||||
|
||||
fn div_mut(&mut self, other: &Self) -> &Self {
|
||||
*self /= other;
|
||||
self
|
||||
}
|
||||
|
||||
fn sum(&self) -> T {
|
||||
self.sum()
|
||||
}
|
||||
|
||||
fn unique(&self) -> Vec<T> {
|
||||
let mut result = self.clone().into_raw_vec();
|
||||
result.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
result.dedup();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RealNumber + ScalarOperand + AddAssign + SubAssign + MulAssign + DivAssign + Sum>
|
||||
|
||||
Reference in New Issue
Block a user