diff --git a/src/impls/mod.rs b/src/impls/mod.rs index 7865d1a0..ce926498 100644 --- a/src/impls/mod.rs +++ b/src/impls/mod.rs @@ -1,3 +1,2 @@ //! Implement trait bindings of LAPACK -pub mod outer; pub mod solve; diff --git a/src/impls/outer.rs b/src/impls/outer.rs deleted file mode 100644 index 2b028dc2..00000000 --- a/src/impls/outer.rs +++ /dev/null @@ -1,18 +0,0 @@ - -use blas::c::{Layout, dger, sger}; - -pub trait ImplOuter: Sized { - fn outer(m: usize, n: usize, a: &[Self], b: &[Self], ab: &mut [Self]); -} - -macro_rules! impl_cholesky { - ($scalar:ty, $ger:path) => { -impl ImplOuter for $scalar { - fn outer(m: usize, n: usize, a: &[Self], b: &[Self], mut ab: &mut [Self]) { - $ger(Layout::ColumnMajor, m as i32, n as i32, 1.0, a, 1, b, 1, ab, m as i32); - } -} -}} // end macro_rules - -impl_cholesky!(f64, dger); -impl_cholesky!(f32, sger); diff --git a/src/vector.rs b/src/vector.rs index 2cca3d4a..46b88f88 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -1,11 +1,14 @@ //! Define trait for vectors use std::iter::Sum; -use ndarray::{Array, NdFloat, Ix1, Ix2, LinalgScalar, ArrayBase, Data, Dimension}; -use num_traits::float::Float; -use super::impls::outer::ImplOuter; +use ndarray::*; +use num_traits::Float; -/// Norms of ndarray +use super::types::*; + +/// Define norm as a metric linear space (not as a matrix) +/// +/// For operator norms, see opnorm module pub trait Norm { type Output; /// rename of `norm_l2` @@ -31,7 +34,7 @@ impl Norm for ArrayBase self.iter().map(|x| x.abs()).sum() } fn norm_l2(&self) -> Self::Output { - self.iter().map(|x| x.sq_abs()).sum::().sqrt() + self.iter().map(|x| x.squared()).sum::().sqrt() } fn norm_max(&self) -> Self::Output { self.iter().fold(T::zero(), |f, &val| { @@ -44,35 +47,36 @@ impl Norm for ArrayBase /// Field with norm pub trait Absolute { type Output: Float; - fn sq_abs(&self) -> Self::Output; + fn squared(&self) -> Self::Output; fn abs(&self) -> Self::Output { - self.sq_abs().sqrt() + self.squared().sqrt() } } -impl Absolute for A { - type Output = A; - fn sq_abs(&self) -> A { +macro_rules! impl_abs { + ($f:ty, $c:ty) => { + +impl Absolute for $f { + type Output = Self; + fn squared(&self) -> Self::Output { *self * *self } - fn abs(&self) -> A { + fn abs(&self) -> Self::Output { Float::abs(*self) } } -/// Outer product -pub fn outer(a: &ArrayBase, b: &ArrayBase) -> Array - where A: NdFloat + ImplOuter, - S1: Data, - S2: Data -{ - let m = a.len(); - let n = b.len(); - let mut ab = Array::zeros((n, m)); - ImplOuter::outer(m, - n, - a.as_slice_memory_order().unwrap(), - b.as_slice_memory_order().unwrap(), - ab.as_slice_memory_order_mut().unwrap()); - ab.reversed_axes() +impl Absolute for $c { + type Output = $f; + fn squared(&self) -> Self::Output { + self.norm_sqr() + } + fn abs(&self) -> Self::Output { + self.norm() + } } + +}} // impl_abs! + +impl_abs!(f64, c64); +impl_abs!(f32, c32); diff --git a/tests/outer.rs b/tests/outer.rs deleted file mode 100644 index bd3ec130..00000000 --- a/tests/outer.rs +++ /dev/null @@ -1,38 +0,0 @@ -include!("header.rs"); -use ndarray_linalg::vector::outer; - -#[test] -fn outer_3x4() { - let dist = RealNormal::::new(0.0, 1.0); - let m = 3; - let n = 4; - let a = Array::random(m, dist); - let b = Array::random(n, dist); - println!("a = \n{:?}", &a); - println!("b = \n{:?}", &b); - let ab = outer(&a, &b); - println!("ab = \n{:?}", &ab); - for i in 0..m { - for j in 0..n { - assert_rclose!(ab[(i, j)], a[i] * b[j], 1e-7); - } - } -} - -#[test] -fn outer_4x3() { - let dist = RealNormal::::new(0.0, 1.0); - let m = 4; - let n = 3; - let a = Array::random(m, dist); - let b = Array::random(n, dist); - println!("a = \n{:?}", &a); - println!("b = \n{:?}", &b); - let ab = outer(&a, &b); - println!("ab = \n{:?}", &ab); - for i in 0..m { - for j in 0..n { - assert_rclose!(ab[(i, j)], a[i] * b[j], 1e-7); - } - } -}