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
#![doc="Functions for vectors
For many operations below,
it doesn't matter whether the vector is a column vector
or a row vector. The stride is always one in both cases.
"]
use num::traits::{One, Zero};
use algebra::structure::{MagmaBase, CommutativeMonoidAddPartial, CommutativeRingPartial};
use matrix::matrix::Matrix;
use matrix::traits::{Shape, MatrixBuffer};
pub struct VecIterator<T:MagmaBase> {
ptr : *const T,
pos : usize,
len : usize
}
impl <T:MagmaBase> VecIterator<T> {
pub fn new (ptr: *const T, len : usize)->VecIterator<T>{
VecIterator{ptr: ptr, pos : 0, len : len}
}
}
impl<T:MagmaBase> Iterator for VecIterator<T>{
type Item = T;
fn next(&mut self)->Option<T> {
if self.pos == self.len {
return None;
}
let offset = self.pos;
self.pos += 1;
Some(unsafe{*self.ptr.offset(offset as isize)})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.len - self.pos;
(n, Some(n))
}
}
pub fn vec_iter<T:MagmaBase>(m : &Matrix<T>) -> VecIterator<T> {
assert!(m.is_vector());
VecIterator::new(m.as_ptr(), m.num_cells())
}
pub fn vec_reduce_sum<T:CommutativeMonoidAddPartial>(v : &Matrix<T>) -> T{
let mut result : T = Zero::zero();
for entry in vec_iter(v){
result = result + entry;
}
result
}
pub fn vec_reduce_product<T:CommutativeRingPartial>(v : &Matrix<T>) -> T{
let mut result : T = One::one();
for entry in vec_iter(v){
result = result * entry;
}
result
}
#[cfg(test)]
mod test{
use super::*;
use matrix::traits::*;
use matrix::constructors::*;
#[test]
fn test_vec_iter(){
let v = vector_i64(&[1, 2, 3, 4]);
assert!(v.is_col());
let mut i = vec_iter(&v);
assert_eq!(i.next(), Some(1));
assert_eq!(i.next(), Some(2));
assert_eq!(i.next(), Some(3));
assert_eq!(i.next(), Some(4));
assert_eq!(i.next(), None);
let v = v.transpose();
assert!(v.is_row());
let mut i = vec_iter(&v);
assert_eq!(i.next(), Some(1));
assert_eq!(i.next(), Some(2));
assert_eq!(i.next(), Some(3));
assert_eq!(i.next(), Some(4));
assert_eq!(i.next(), None);
}
#[test]
fn test_vec_reduce_sum(){
let v = vector_i64(&[1, 2, 3, 4]);
assert_eq!(vec_reduce_sum(&v), 10);
let v = v.transpose();
assert_eq!(vec_reduce_sum(&v), 10);
}
#[test]
fn test_vec_reduce_prod(){
let v = vector_i64(&[1, 2, 3, 4]);
assert_eq!(vec_reduce_product(&v), 24);
let v = v.transpose();
assert_eq!(vec_reduce_product(&v), 24);
}
}