Implement Outer for DVec. (#186)

Fix #181.
This commit is contained in:
Sébastien Crozet 2016-04-17 13:20:58 +02:00
parent 9e739676a7
commit 9a87e2360d
2 changed files with 30 additions and 2 deletions

View File

@ -7,7 +7,8 @@ use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssi
use std::mem; use std::mem;
use rand::{self, Rand}; use rand::{self, Rand};
use num::{Zero, One}; use num::{Zero, One};
use traits::operations::{ApproxEq, Axpy, Mean}; use structs::DMat;
use traits::operations::{ApproxEq, Axpy, Mean, Outer};
use traits::geometry::{Dot, Norm}; use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast}; use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
@ -57,7 +58,7 @@ impl<N> DVec<N> {
/// Builds a vector filled with the results of a function applied to each of its component coordinates. /// Builds a vector filled with the results of a function applied to each of its component coordinates.
#[inline(always)] #[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> DVec<N> { pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> DVec<N> {
DVec { at: (0..dim).map(|i| f(i)).collect() } DVec { at: (0 .. dim).map(|i| f(i)).collect() }
} }
/// The vector length. /// The vector length.
@ -74,6 +75,25 @@ impl<N> FromIterator<N> for DVec<N> {
} }
} }
impl<N: Copy + BaseNum> Outer for DVec<N> {
type OuterProductType = DMat<N>;
#[inline]
fn outer(&self, other: &DVec<N>) -> DMat<N> {
let mut res = unsafe { DMat::new_uninitialized(self.at.len(), other.at.len()) };
for i in 0 .. self.at.len() {
for j in 0 .. other.at.len() {
unsafe {
res.unsafe_set((i, j), self.unsafe_at(i) * other.unsafe_at(j));
}
}
}
res
}
}
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for DVec<N> { impl<N: Arbitrary> Arbitrary for DVec<N> {
fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> { fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> {

View File

@ -835,3 +835,11 @@ fn test_transpose_square_mat() {
assert_eq!(&[0, 1, 2, 3], &mat.row_slice(i, 0, num_cols)[..]); assert_eq!(&[0, 1, 2, 3], &mat.row_slice(i, 0, num_cols)[..]);
} }
} }
#[test]
fn test_outer_dvec() {
let vec = DVec::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
let row = DMat::from_row_vec(1, 5, &vec[..]);
assert_eq!(row.transpose() * row, na::outer(&vec, &vec))
}