<commit_before>// Copyright 2015 <NAME>. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::ops::{
    Mul,
};
use default::Default;
use vector::Vector;
use matrix_vector::ops::*;
use matrix::Matrix;
use math::Trans;
use math::Mat;

impl<'a, T, V> Mul<&'a V> for &'a Matrix<T>
    where T: Default + Copy + Gemv,
          V: Vector<T>,
{
    type Output = Vec<T>;

    fn mul(self, x: &'a V) -> Vec<T> {
        let n = self.rows() as usize;
        let mut result = Vec::with_capacity(n);
        unsafe { result.set_len(n); }
        let scale = Default::one();
        let clear = Default::zero();

        Gemv::gemv(&scale, self, x, &clear, &mut result);
        result
    }
}

impl<'a, T> Mul<Trans<&'a Vector<T>>> for &'a Vector<T>
    where T: Default + Ger + Gerc + Clone,
{
    type Output = Mat<T>;

    fn mul(self, x: Trans<&'a Vector<T>>) -> Mat<T> {
        let n = self.len() as usize;
        let m = (*x).len() as usize;
        let mut result = Mat::fill(Default::zero(), n, m);
        let scale = Default::one();

        match x {
            Trans::T(v) => Ger::ger(&scale, self, v, &mut result),
            Trans::H(v) => Gerc::gerc(&scale, self, v, &mut result),
        }

        result
    }
}

#[cfg(test)]
mod tests {
    use Vector;
    use Matrix;

    #[test]
    fn mul() {
        let a = (2, 2, vec![2.0, -2.0, 2.0, -4.0]);
        let x = vec![2.0, 1.0];

        let y = {
            let ar = &a as &Matrix<_>;
            ar * &x
        };

        assert_eq!(y, vec![2.0, 0.0]);
    }
}<commit_msg>Test outer product<commit_after>// Copyright 2015 <NAME>. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::ops::{
    Mul,
};
use default::Default;
use vector::Vector;
use matrix_vector::ops::*;
use matrix::Matrix;
use math::Trans;
use math::Mat;

impl<'a, T, V> Mul<&'a V> for &'a Matrix<T>
    where T: Default + Copy + Gemv,
          V: Vector<T>,
{
    type Output = Vec<T>;

    fn mul(self, x: &'a V) -> Vec<T> {
        let n = self.rows() as usize;
        let mut result = Vec::with_capacity(n);
        unsafe { result.set_len(n); }
        let scale = Default::one();
        let clear = Default::zero();

        Gemv::gemv(&scale, self, x, &clear, &mut result);
        result
    }
}

impl<'a, T> Mul<Trans<&'a Vector<T>>> for &'a Vector<T>
    where T: Default + Ger + Gerc + Clone,
{
    type Output = Mat<T>;

    fn mul(self, x: Trans<&'a Vector<T>>) -> Mat<T> {
        let n = self.len() as usize;
        let m = (*x).len() as usize;
        let mut result = Mat::fill(Default::zero(), n, m);
        let scale = Default::one();

        match x {
            Trans::T(v) => Ger::ger(&scale, self, v, &mut result),
            Trans::H(v) => Gerc::gerc(&scale, self, v, &mut result),
        }

        result
    }
}

#[cfg(test)]
mod tests {
    use Vector;
    use Matrix;
    use math::Mat;
    use math::Marker::T;

    #[test]
    fn mul() {
        let a = (2, 2, vec![2.0, -2.0, 2.0, -4.0]);
        let x = vec![2.0, 1.0];

        let y = {
            let ar = &a as &Matrix<_>;
            ar * &x
        };

        assert_eq!(y, vec![2.0, 0.0]);
    }

    #[test]
    fn outer() {
        let x = vec![2.0, 1.0, 4.0];
        let y = vec![3.0, 6.0, -1.0];

        let a = {
            let xr = &x as &Vector<_>;
            let yr = &y as &Vector<_>;

            xr * (yr ^ T)
        };

        let result = mat![  6.0, 12.0, -2.0;
                            3.0, 6.0, -1.0;
                            12.0, 24.0, -4.0];
        assert_eq!(a, result);
    }
}
{'fraction_non_alphanumeric': 0.1829432337906914, 'fraction_numerical': 0.02071563088512241, 'mean_word_length': 1.8622016936104695, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1430006', 'n_tokens_mistral': 1387, 'n_tokens_neox': 1360, 'n_words': 406}