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
use crate::MutVecg;
use indxvec::Vecops;

/// Mutable vector operations on `&mut [f64]`, where the operand endtype is generic
impl MutVecg for &mut [f64] {
    /// Scalar multiplication of a vector, mutates self
    fn mutsmult<U:PartialOrd+Into<f64>>(self, s: U)
    {
        let sf = s.into();
        self.iter_mut().for_each(|x| *x *= sf);
    }

    /// Vector subtraction, mutates self
    fn mutvsub<U:Clone+PartialOrd+Into<f64>>(self, v: &[U])
    {
        self.iter_mut()
            .zip(v)
            .for_each(|(x, vi)| *x -= vi.clone().into())
    }

    /// Vector addition, mutates self
    fn mutvadd<U:Clone+PartialOrd+Into<f64>>(self, v: &[U])
    {
        self.iter_mut()
            .zip(v)
            .for_each(|(x, vi)| *x += vi.clone().into())
    }

    /// Vector with inverse magnitude
    fn minvert(self) {
        let recmag2 = 1.0 / self.iter().map(|&x| x.powi(2)).sum::<f64>();
        for c in self.iter_mut() {
            *c *= recmag2
        }
    }

    // negated vector (all components swap sign)
    fn mneg(self) {
        for c in self.iter_mut() {
            *c *= -1_f64
        }
    }

    /// Unit vector
    fn munit(self) {
        let m = (1.0 / self.iter().map(|&x| x.powi(2)).sum::<f64>()).sqrt();
        for c in self.iter_mut() {
            *c *= m
        }
    }

    /// Linear transform to interval [0,1]
    fn mlintrans(self) {
        let mm = self.minmax();
        let range = mm.max - mm.min;
        for c in self.iter_mut() {
            *c = (*c - mm.min) / range
        }
    }
}