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}