peroxide/traits/
sugar.rs

1use crate::structure::matrix::{matrix, Matrix, Shape};
2use crate::traits::fp::FPVector;
3use crate::traits::matrix::MatrixTrait;
4use crate::util::non_macro::zeros_shape;
5use std::ops::{Add, Div, Mul, Sub};
6
7/// Syntactic sugar for Vector operations
8pub trait VecOps: Sized + FPVector
9where
10    Self::Scalar: Copy
11        + Clone
12        + Add<Self::Scalar, Output = Self::Scalar>
13        + Sub<Self::Scalar, Output = Self::Scalar>
14        + Mul<Self::Scalar, Output = Self::Scalar>
15        + Div<Self::Scalar, Output = Self::Scalar>,
16{
17    //type Scalar;
18    fn add_v(&self, v: &Self) -> Self {
19        self.zip_with(|x, y| x + y, v)
20    }
21    fn sub_v(&self, v: &Self) -> Self {
22        self.zip_with(|x, y| x - y, v)
23    }
24    fn mul_v(&self, v: &Self) -> Self {
25        self.zip_with(|x, y| x * y, v)
26    }
27    fn div_v(&self, v: &Self) -> Self {
28        self.zip_with(|x, y| x / y, v)
29    }
30    fn add_s(&self, s: Self::Scalar) -> Self {
31        self.fmap(|x| x + s)
32    }
33    fn sub_s(&self, s: Self::Scalar) -> Self {
34        self.fmap(|x| x - s)
35    }
36    fn mul_s(&self, s: Self::Scalar) -> Self {
37        self.fmap(|x| x * s)
38    }
39    fn div_s(&self, s: Self::Scalar) -> Self {
40        self.fmap(|x| x / s)
41    }
42}
43
44pub trait Scalable {
45    type Vec;
46    fn reshape(&self, size: (usize, usize), shape: Shape) -> Matrix;
47    fn add_col(&self, v: &Self::Vec) -> Matrix;
48    fn add_row(&self, v: &Self::Vec) -> Matrix;
49}
50
51pub trait ScalableMut {
52    type Vec;
53    fn reshape_mut(&mut self, size: (usize, usize), shape: Shape);
54    fn add_col_mut(&mut self, v: &Self::Vec);
55    fn add_row_mut(&mut self, v: &Self::Vec);
56}
57
58pub trait ConvToMat {
59    fn to_col(&self) -> Matrix;
60    fn to_row(&self) -> Matrix;
61}
62
63// =============================================================================
64// Implementations
65// =============================================================================
66
67impl VecOps for Vec<f64> {}
68//    /// Vector + Vector
69//    ///
70//    /// ```
71//    /// #[macro_use]
72//    /// extern crate peroxide;
73//    /// use peroxide::fuga::*;
74//    ///
75//    /// fn main() {
76//    ///     let a = c!(1,2,3,4,5);
77//    ///     let b = c!(5,4,3,2,1);
78//    ///     assert_eq!(a.add_v(&b), c!(6,6,6,6,6));
79//    /// }
80//    /// ```
81//    fn add_v(&self, v: &Self) -> Self {
82//        self.add_vec(&v)
83//    }
84//
85//    /// Vector - Vector
86//    ///
87//    /// ```
88//    /// #[macro_use]
89//    /// extern crate peroxide;
90//    /// use peroxide::fuga::*;
91//    ///
92//    /// fn main() {
93//    ///     let a = c!(1,2,3,4,5);
94//    ///     let b = c!(5,4,3,2,1);
95//    ///     assert_eq!(a.sub_v(&b), c!(-4, -2, 0, 2, 4));
96//    /// }
97//    /// ```
98//    fn sub_v(&self, v: &Self) -> Self {
99//        self.zip_with(|x, y| x - y, v)
100//    }
101//
102//    /// Vector * Vector
103//    ///
104//    /// ```
105//    /// #[macro_use]
106//    /// extern crate peroxide;
107//    /// use peroxide::fuga::*;
108//    ///
109//    /// fn main() {
110//    ///     let a = c!(1,2,3,4,5);
111//    ///     let b = c!(5,4,3,2,1);
112//    ///     assert_eq!(a.mul_v(&b), c!(5, 8, 9, 8, 5));
113//    /// }
114//    /// ```
115//    fn mul_v(&self, v: &Self) -> Self {
116//        self.zip_with(|x, y| x * y, v)
117//    }
118//
119//    /// Vector / Vector
120//    ///
121//    /// ```
122//    /// #[macro_use]
123//    /// extern crate peroxide;
124//    /// use peroxide::fuga::*;
125//    ///
126//    /// fn main() {
127//    ///     let a = c!(2, 4, 6, 8, 10);
128//    ///     let b = c!(2, 2, 2, 2, 2);
129//    ///     assert_eq!(a.div_v(&b), c!(1,2,3,4,5));
130//    /// }
131//    /// ```
132//    fn div_v(&self, v: &Self) -> Self {
133//        self.zip_with(|x, y| x / y, v)
134//    }
135//
136//    /// Vector + Scalar
137//    ///
138//    /// ```
139//    /// #[macro_use]
140//    /// extern crate peroxide;
141//    /// use peroxide::fuga::*;
142//    ///
143//    /// fn main() {
144//    ///     let a = c!(1,2,3,4,5);
145//    ///     let b = 1f64;
146//    ///     assert_eq!(a.add_s(b), c!(2,3,4,5,6));
147//    /// }
148//    /// ```
149//    fn add_s(&self, s: Self::Scalar) -> Self {
150//        self.fmap(|x| x + s)
151//    }
152//
153//    /// Vector - Scalar
154//    ///
155//    /// ```
156//    /// #[macro_use]
157//    /// extern crate peroxide;
158//    /// use peroxide::fuga::*;
159//    ///
160//    /// fn main() {
161//    ///     let a = c!(1,2,3,4,5);
162//    ///     let b = 1f64;
163//    ///     assert_eq!(a.sub_s(b), c!(0,1,2,3,4));
164//    /// }
165//    /// ```
166//    fn sub_s(&self, s: Self::Scalar) -> Self {
167//        self.fmap(|x| x - s)
168//    }
169//
170//    /// Vector * Scalar
171//    ///
172//    /// ```
173//    /// #[macro_use]
174//    /// extern crate peroxide;
175//    /// use peroxide::fuga::*;
176//    ///
177//    /// fn main() {
178//    ///     let a = c!(1,2,3,4,5);
179//    ///     let b = 2f64;
180//    ///     assert_eq!(a.mul_s(b), c!(2,4,6,8,10));
181//    /// }
182//    /// ```
183//    fn mul_s(&self, s: Self::Scalar) -> Self {
184//        self.mul_scalar(s)
185//    }
186//
187//    /// Vector / Scalar
188//    ///
189//    /// ```
190//    /// #[macro_use]
191//    /// extern crate peroxide;
192//    /// use peroxide::fuga::*;
193//    ///
194//    /// fn main() {
195//    ///     let a = c!(2,4,6,8,10);
196//    ///     let b = 2f64;
197//    ///     assert_eq!(a.div_s(b), c!(1,2,3,4,5));
198//    /// }
199//    /// ```
200//    fn div_s(&self, s: Self::Scalar) -> Self {
201//        self.fmap(|x| x / s)
202//    }
203
204impl Scalable for Vec<f64> {
205    type Vec = Self;
206
207    /// Vector to Matrix
208    ///
209    /// ```
210    /// #[macro_use]
211    /// extern crate peroxide;
212    /// use peroxide::fuga::*;
213    ///
214    /// fn main() {
215    ///     let a = c!(1,2,3,4,5,6);
216    ///     let b1 = a.reshape((3,2), Row);
217    ///     let b2 = a.reshape((3,2), Col);
218    ///     assert_eq!(b1, ml_matrix("1 2;3 4;5 6"));
219    ///     assert_eq!(b2, ml_matrix("1 4;2 5;3 6"));
220    /// }
221    /// ```
222    fn reshape(&self, (r, c): (usize, usize), shape: Shape) -> Matrix {
223        assert_eq!(self.len(), r * c);
224        let mut m = zeros_shape(r, c, shape);
225        m.data = self[..].to_vec();
226        m
227    }
228
229    /// Vector + Vector = Matrix
230    ///
231    /// ```
232    /// #[macro_use]
233    /// extern crate peroxide;
234    /// use peroxide::fuga::*;
235    ///
236    /// fn main() {
237    ///     let a = c!(1,2,3);
238    ///     let b = c!(4,5,6);
239    ///     let c1 = a.add_row(&b);
240    ///     let c2 = a.add_col(&b);
241    ///     assert_eq!(c1, ml_matrix("1 2 3;4 5 6"));
242    ///     assert_eq!(c2, ml_matrix("1 4;2 5;3 6"));
243    /// }
244    /// ```
245    fn add_col(&self, v: &Self::Vec) -> Matrix {
246        assert_eq!(self.len(), v.len());
247        let mut x = self[..].to_vec();
248        x.extend_from_slice(&v[..]);
249        x.reshape((self.len(), 2), Shape::Col)
250    }
251
252    /// Vector + Vector = Matrix
253    ///
254    /// ```
255    /// #[macro_use]
256    /// extern crate peroxide;
257    /// use peroxide::fuga::*;
258    ///
259    /// fn main() {
260    ///     let a = c!(1,2,3);
261    ///     let b = c!(4,5,6);
262    ///     let c1 = a.add_row(&b);
263    ///     let c2 = a.add_col(&b);
264    ///     assert_eq!(c1, ml_matrix("1 2 3;4 5 6"));
265    ///     assert_eq!(c2, ml_matrix("1 4;2 5;3 6"));
266    /// }
267    /// ```
268    fn add_row(&self, v: &Self::Vec) -> Matrix {
269        assert_eq!(self.len(), v.len());
270        let mut x = self[..].to_vec();
271        x.extend_from_slice(&v[..]);
272        x.reshape((2, self.len()), Shape::Row)
273    }
274}
275
276/// Modify Matrix
277impl Scalable for Matrix {
278    type Vec = Vec<f64>;
279
280    /// Resize matrix
281    ///
282    /// ```
283    /// #[macro_use]
284    /// extern crate peroxide;
285    /// use peroxide::fuga::*;
286    ///
287    /// fn main() {
288    ///     let a = ml_matrix("1 2 3;4 5 6"); // ml_matrix has shape `Col`
289    ///     let b1 = a.reshape((3, 2), Row);
290    ///     let b2 = a.reshape((3, 2), Col);
291    ///     assert_eq!(b1, ml_matrix("1 2;3 4;5 6"));
292    ///     assert_eq!(b2, ml_matrix("1 4;2 5;3 6"));
293    /// }
294    /// ```
295    fn reshape(&self, (r, c): (usize, usize), shape: Shape) -> Matrix {
296        assert_eq!(self.row * self.col, r * c);
297        let mut m = zeros_shape(r, c, shape);
298        m.data = self.data[..].to_vec();
299        m
300    }
301
302    /// Add column
303    ///
304    /// ```
305    /// #[macro_use]
306    /// extern crate peroxide;
307    /// use peroxide::fuga::*;
308    ///
309    /// fn main() {
310    ///     let a = ml_matrix("1 2 3;4 5 6");
311    ///     let b = c!(7,8);
312    ///     let c = a.add_col(&b);
313    ///     assert_eq!(c, ml_matrix("1 2 3 7;4 5 6 8"));
314    /// }
315    /// ```
316    fn add_col(&self, v: &Self::Vec) -> Matrix {
317        assert_eq!(self.row, v.len());
318        match self.shape {
319            Shape::Col => {
320                let mut m = self.clone();
321                m.data.extend_from_slice(&v[..]);
322                m.col += 1;
323                m
324            }
325            Shape::Row => {
326                let mut m = self.change_shape();
327                m.data.extend_from_slice(&v[..]);
328                m.col += 1;
329                m
330            }
331        }
332    }
333
334    /// Add row
335    ///
336    /// ```
337    /// #[macro_use]
338    /// extern crate peroxide;
339    /// use peroxide::fuga::*;
340    ///
341    /// fn main() {
342    ///     let a = ml_matrix("1 2 3;4 5 6");
343    ///     let b = c!(7,8,9);
344    ///     let c = a.add_row(&b);
345    ///     assert_eq!(c, ml_matrix("1 2 3;4 5 6;7 8 9"));
346    /// }
347    /// ```
348    fn add_row(&self, v: &Self::Vec) -> Matrix {
349        assert_eq!(self.col, v.len());
350        match self.shape {
351            Shape::Row => {
352                let mut m = self.clone();
353                m.data.extend_from_slice(&v[..]);
354                m.row += 1;
355                m
356            }
357            Shape::Col => {
358                let mut m = self.change_shape();
359                m.data.extend_from_slice(&v[..]);
360                m.row += 1;
361                m
362            }
363        }
364    }
365}
366
367impl ScalableMut for Matrix {
368    type Vec = Vec<f64>;
369
370    /// Resize matrix (Mutable)
371    ///
372    /// ```
373    /// #[macro_use]
374    /// extern crate peroxide;
375    /// use peroxide::fuga::*;
376    ///
377    /// fn main() {
378    ///     let mut a = ml_matrix("1 2 3;4 5 6"); // ml_matrix has shape `Row`
379    ///     a.reshape_mut((3, 2), Row);
380    ///     assert_eq!(a, ml_matrix("1 2;3 4;5 6"));
381    ///     a.reshape_mut((3, 2), Col);
382    ///     assert_eq!(a, ml_matrix("1 4;2 5;3 6"));
383    /// }
384    /// ```
385    fn reshape_mut(&mut self, (r, c): (usize, usize), shape: Shape) {
386        assert_eq!(self.row * self.col, r * c);
387        self.row = r;
388        self.col = c;
389        self.shape = shape;
390    }
391
392    /// Add column (Mutable)
393    ///
394    /// ```
395    /// #[macro_use]
396    /// extern crate peroxide;
397    /// use peroxide::fuga::*;
398    ///
399    /// fn main() {
400    ///     let mut a = ml_matrix("1 2 3;4 5 6");
401    ///     let b = c!(7,8);
402    ///     a.add_col_mut(&b);
403    ///     assert_eq!(a, ml_matrix("1 2 3 7;4 5 6 8"));
404    /// }
405    /// ```
406    fn add_col_mut(&mut self, v: &Self::Vec) {
407        assert_eq!(self.row, v.len());
408        match self.shape {
409            Shape::Col => {
410                self.data.extend_from_slice(&v[..]);
411                self.col += 1;
412            }
413            Shape::Row => {
414                self.change_shape_mut();
415                self.data.extend_from_slice(&v[..]);
416                self.col += 1;
417            }
418        }
419    }
420
421    /// Add row (Mutable)
422    ///
423    /// ```
424    /// #[macro_use]
425    /// extern crate peroxide;
426    /// use peroxide::fuga::*;
427    ///
428    /// fn main() {
429    ///     let mut a = ml_matrix("1 2 3;4 5 6");
430    ///     let b = c!(7,8,9);
431    ///     a.add_row_mut(&b);
432    ///     assert_eq!(a, ml_matrix("1 2 3;4 5 6;7 8 9"));
433    /// }
434    /// ```
435    fn add_row_mut(&mut self, v: &Self::Vec) {
436        assert_eq!(self.col, v.len());
437        match self.shape {
438            Shape::Row => {
439                self.data.extend_from_slice(&v[..]);
440                self.row += 1;
441            }
442            Shape::Col => {
443                self.change_shape_mut();
444                self.data.extend_from_slice(&v[..]);
445                self.row += 1;
446            }
447        }
448    }
449}
450
451impl ConvToMat for Vec<f64> {
452    fn to_col(&self) -> Matrix {
453        matrix(self.clone(), self.len(), 1, Shape::Col)
454    }
455
456    fn to_row(&self) -> Matrix {
457        matrix(self.clone(), 1, self.len(), Shape::Row)
458    }
459}