com_croftsoft_core/math/matrix/operations/
mod.rs

1// =============================================================================
2//! - Overloaded operators for the structure Matrix
3//! - Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign
4//!
5//! # Metadata
6//! - Copyright: © 1998 - 2022 [`CroftSoft Inc`]
7//! - Author: [`David Wallace Croft`]
8//! - Rust version: 2022-09-29
9//! - Rust since: 2022-09-04
10//! - Java version: 1998-12-27
11//!
12//! # History
13//! - Adapted from the Java class com.croftsoft.core.math.Matrix
14//!   - In the Java-based [`CroftSoft Core Library`]
15//!
16//! [`CroftSoft Core Library`]: https://www.croftsoft.com/library/code/
17//! [`CroftSoft Inc`]: https://www.croftsoft.com/
18//! [`David Wallace Croft`]: https://www.croftsoft.com/people/david/
19// =============================================================================
20
21#[cfg(test)]
22mod test;
23
24use super::structures::*;
25use std::ops::{
26  Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
27};
28
29// Operator Add ----------------------------------------------------------------
30
31impl<const R: usize, const C: usize> Add<Matrix<R, C>> for f64 {
32  type Output = Matrix<R, C>;
33
34  fn add(
35    self,
36    rhs: Matrix<R, C>,
37  ) -> Self::Output {
38    Matrix::add_matrix_with_scalar(&rhs, self)
39  }
40}
41
42impl<const R: usize, const C: usize> Add<&Matrix<R, C>> for f64 {
43  type Output = Matrix<R, C>;
44
45  fn add(
46    self,
47    rhs: &Matrix<R, C>,
48  ) -> Self::Output {
49    Matrix::add_matrix_with_scalar(rhs, self)
50  }
51}
52
53impl<const R: usize, const C: usize> Add<f64> for Matrix<R, C> {
54  type Output = Matrix<R, C>;
55
56  fn add(
57    self,
58    rhs: f64,
59  ) -> Self::Output {
60    Self::add_matrix_with_scalar(&self, rhs)
61  }
62}
63
64impl<const R: usize, const C: usize> Add<f64> for &Matrix<R, C> {
65  type Output = Matrix<R, C>;
66
67  fn add(
68    self,
69    rhs: f64,
70  ) -> Self::Output {
71    Matrix::add_matrix_with_scalar(self, rhs)
72  }
73}
74
75impl<const R: usize, const C: usize> Add<Matrix<R, C>> for Matrix<R, C> {
76  type Output = Matrix<R, C>;
77
78  fn add(
79    self,
80    rhs: Matrix<R, C>,
81  ) -> Self::Output {
82    Self::add_matrix_with_matrix(&self, &rhs)
83  }
84}
85
86impl<const R: usize, const C: usize> Add<&Matrix<R, C>> for Matrix<R, C> {
87  type Output = Matrix<R, C>;
88
89  fn add(
90    self,
91    rhs: &Matrix<R, C>,
92  ) -> Self::Output {
93    Self::add_matrix_with_matrix(&self, rhs)
94  }
95}
96
97impl<const R: usize, const C: usize> Add<Matrix<R, C>> for &Matrix<R, C> {
98  type Output = Matrix<R, C>;
99
100  fn add(
101    self,
102    rhs: Matrix<R, C>,
103  ) -> Self::Output {
104    Matrix::add_matrix_with_matrix(self, &rhs)
105  }
106}
107
108impl<'a, 'b, const R: usize, const C: usize> Add<&'b Matrix<R, C>>
109  for &'a Matrix<R, C>
110{
111  type Output = Matrix<R, C>;
112
113  fn add(
114    self,
115    rhs: &'b Matrix<R, C>,
116  ) -> Self::Output {
117    Matrix::add_matrix_with_matrix(self, rhs)
118  }
119}
120
121// Operator AddAssign ----------------------------------------------------------
122
123impl<const R: usize, const C: usize> AddAssign<f64> for Matrix<R, C> {
124  fn add_assign(
125    &mut self,
126    rhs: f64,
127  ) {
128    self.add_scalar(rhs);
129  }
130}
131
132impl<const R: usize, const C: usize> AddAssign<f64> for &mut Matrix<R, C> {
133  fn add_assign(
134    &mut self,
135    rhs: f64,
136  ) {
137    self.add_scalar(rhs);
138  }
139}
140
141impl<const R: usize, const C: usize> AddAssign<Matrix<R, C>> for Matrix<R, C> {
142  fn add_assign(
143    &mut self,
144    rhs: Matrix<R, C>,
145  ) {
146    self.add_matrix(&rhs);
147  }
148}
149
150impl<const R: usize, const C: usize> AddAssign<Matrix<R, C>>
151  for &mut Matrix<R, C>
152{
153  fn add_assign(
154    &mut self,
155    rhs: Matrix<R, C>,
156  ) {
157    self.add_matrix(&rhs);
158  }
159}
160
161impl<const R: usize, const C: usize> AddAssign<&Matrix<R, C>> for Matrix<R, C> {
162  fn add_assign(
163    &mut self,
164    rhs: &Matrix<R, C>,
165  ) {
166    self.add_matrix(rhs);
167  }
168}
169
170impl<const R: usize, const C: usize> AddAssign<&Matrix<R, C>>
171  for &mut Matrix<R, C>
172{
173  fn add_assign(
174    &mut self,
175    rhs: &Matrix<R, C>,
176  ) {
177    self.add_matrix(rhs);
178  }
179}
180
181// Operator Div ----------------------------------------------------------------
182
183impl<const R: usize, const C: usize> Div<f64> for Matrix<R, C> {
184  type Output = Self;
185
186  fn div(
187    self,
188    rhs: f64,
189  ) -> Self::Output {
190    Self::divide_matrix_by_scalar(&self, rhs)
191  }
192}
193
194impl<const R: usize, const C: usize> Div<f64> for &Matrix<R, C> {
195  type Output = Matrix<R, C>;
196
197  fn div(
198    self,
199    rhs: f64,
200  ) -> Self::Output {
201    Matrix::divide_matrix_by_scalar(self, rhs)
202  }
203}
204
205// Operator DivAssign ----------------------------------------------------------
206
207impl<const R: usize, const C: usize> DivAssign<f64> for Matrix<R, C> {
208  fn div_assign(
209    &mut self,
210    rhs: f64,
211  ) {
212    self.divide_by_scalar(rhs);
213  }
214}
215
216impl<const R: usize, const C: usize> DivAssign<f64> for &mut Matrix<R, C> {
217  fn div_assign(
218    &mut self,
219    rhs: f64,
220  ) {
221    self.divide_by_scalar(rhs);
222  }
223}
224
225// Operator Mul ----------------------------------------------------------------
226
227impl<const R: usize, const C: usize> Mul<Matrix<R, C>> for f64 {
228  type Output = Matrix<R, C>;
229
230  fn mul(
231    self,
232    rhs: Matrix<R, C>,
233  ) -> Self::Output {
234    Matrix::multiply_matrix_with_scalar(&rhs, self)
235  }
236}
237
238impl<const R: usize, const C: usize> Mul<&Matrix<R, C>> for f64 {
239  type Output = Matrix<R, C>;
240
241  fn mul(
242    self,
243    rhs: &Matrix<R, C>,
244  ) -> Self::Output {
245    Matrix::multiply_matrix_with_scalar(rhs, self)
246  }
247}
248
249impl<const R: usize, const C: usize> Mul<f64> for Matrix<R, C> {
250  type Output = Self;
251
252  fn mul(
253    self,
254    rhs: f64,
255  ) -> Self::Output {
256    Self::multiply_matrix_with_scalar(&self, rhs)
257  }
258}
259
260impl<const R: usize, const C: usize> Mul<f64> for &Matrix<R, C> {
261  type Output = Matrix<R, C>;
262
263  fn mul(
264    self,
265    rhs: f64,
266  ) -> Self::Output {
267    Matrix::multiply_matrix_with_scalar(self, rhs)
268  }
269}
270
271impl<const R: usize, const C: usize, const K: usize> Mul<Matrix<C, K>>
272  for Matrix<R, C>
273{
274  type Output = Matrix<R, K>;
275
276  fn mul(
277    self,
278    rhs: Matrix<C, K>,
279  ) -> Self::Output {
280    Self::multiply_matrix_with_matrix(&self, &rhs)
281  }
282}
283
284impl<const R: usize, const C: usize, const K: usize> Mul<&Matrix<C, K>>
285  for Matrix<R, C>
286{
287  type Output = Matrix<R, K>;
288
289  fn mul(
290    self,
291    rhs: &Matrix<C, K>,
292  ) -> Self::Output {
293    Self::multiply_matrix_with_matrix(&self, rhs)
294  }
295}
296
297impl<const R: usize, const C: usize, const K: usize> Mul<Matrix<C, K>>
298  for &Matrix<R, C>
299{
300  type Output = Matrix<R, K>;
301
302  fn mul(
303    self,
304    rhs: Matrix<C, K>,
305  ) -> Self::Output {
306    Matrix::multiply_matrix_with_matrix(self, &rhs)
307  }
308}
309
310impl<'a, 'b, const R: usize, const C: usize, const K: usize>
311  Mul<&'b Matrix<C, K>> for &'a Matrix<R, C>
312{
313  type Output = Matrix<R, K>;
314
315  fn mul(
316    self,
317    rhs: &'b Matrix<C, K>,
318  ) -> Self::Output {
319    Matrix::multiply_matrix_with_matrix(self, rhs)
320  }
321}
322
323// Operator MulAssign ----------------------------------------------------------
324
325impl<const R: usize, const C: usize> MulAssign<f64> for Matrix<R, C> {
326  fn mul_assign(
327    &mut self,
328    rhs: f64,
329  ) {
330    self.multiply_with_scalar(rhs);
331  }
332}
333
334impl<const R: usize, const C: usize> MulAssign<f64> for &mut Matrix<R, C> {
335  fn mul_assign(
336    &mut self,
337    rhs: f64,
338  ) {
339    self.multiply_with_scalar(rhs);
340  }
341}
342
343impl<const R: usize, const C: usize> MulAssign<Matrix<C, C>> for Matrix<R, C> {
344  fn mul_assign(
345    &mut self,
346    rhs: Matrix<C, C>,
347  ) {
348    self.multiply_with_matrix(&rhs);
349  }
350}
351
352impl<const R: usize, const C: usize> MulAssign<&Matrix<C, C>> for Matrix<R, C> {
353  fn mul_assign(
354    &mut self,
355    rhs: &Matrix<C, C>,
356  ) {
357    self.multiply_with_matrix(rhs);
358  }
359}
360
361impl<const R: usize, const C: usize> MulAssign<Matrix<C, C>>
362  for &mut Matrix<R, C>
363{
364  fn mul_assign(
365    &mut self,
366    rhs: Matrix<C, C>,
367  ) {
368    self.multiply_with_matrix(&rhs);
369  }
370}
371
372impl<const R: usize, const C: usize> MulAssign<&Matrix<C, C>>
373  for &mut Matrix<R, C>
374{
375  fn mul_assign(
376    &mut self,
377    rhs: &Matrix<C, C>,
378  ) {
379    self.multiply_with_matrix(rhs);
380  }
381}
382
383// Operator Neg ----------------------------------------------------------------
384
385impl<const R: usize, const C: usize> Neg for Matrix<R, C> {
386  type Output = Matrix<R, C>;
387
388  fn neg(self) -> Self::Output {
389    Self::negate_matrix(&self)
390  }
391}
392
393impl<const R: usize, const C: usize> Neg for &Matrix<R, C> {
394  type Output = Matrix<R, C>;
395
396  fn neg(self) -> Self::Output {
397    Matrix::negate_matrix(self)
398  }
399}
400
401// Operator Sub ----------------------------------------------------------------
402
403impl<const R: usize, const C: usize> Sub<f64> for Matrix<R, C> {
404  type Output = Matrix<R, C>;
405
406  fn sub(
407    self,
408    rhs: f64,
409  ) -> Self::Output {
410    Self::subtract_scalar_from_matrix(&self, rhs)
411  }
412}
413
414impl<const R: usize, const C: usize> Sub<f64> for &Matrix<R, C> {
415  type Output = Matrix<R, C>;
416
417  fn sub(
418    self,
419    rhs: f64,
420  ) -> Self::Output {
421    Matrix::subtract_scalar_from_matrix(self, rhs)
422  }
423}
424
425impl<const R: usize, const C: usize> Sub<Matrix<R, C>> for f64 {
426  type Output = Matrix<R, C>;
427
428  fn sub(
429    self,
430    rhs: Matrix<R, C>,
431  ) -> Self::Output {
432    Matrix::subtract_matrix_from_scalar(self, &rhs)
433  }
434}
435
436impl<const R: usize, const C: usize> Sub<&Matrix<R, C>> for f64 {
437  type Output = Matrix<R, C>;
438
439  fn sub(
440    self,
441    rhs: &Matrix<R, C>,
442  ) -> Self::Output {
443    Matrix::subtract_matrix_from_scalar(self, rhs)
444  }
445}
446
447impl<const R: usize, const C: usize> Sub<Matrix<R, C>> for Matrix<R, C> {
448  type Output = Matrix<R, C>;
449
450  fn sub(
451    self,
452    rhs: Matrix<R, C>,
453  ) -> Self::Output {
454    Self::subtract_matrix_from_matrix(&self, &rhs)
455  }
456}
457
458impl<const R: usize, const C: usize> Sub<&Matrix<R, C>> for Matrix<R, C> {
459  type Output = Matrix<R, C>;
460
461  fn sub(
462    self,
463    rhs: &Matrix<R, C>,
464  ) -> Self::Output {
465    Self::subtract_matrix_from_matrix(&self, rhs)
466  }
467}
468
469impl<const R: usize, const C: usize> Sub<Matrix<R, C>> for &Matrix<R, C> {
470  type Output = Matrix<R, C>;
471
472  fn sub(
473    self,
474    rhs: Matrix<R, C>,
475  ) -> Self::Output {
476    Matrix::subtract_matrix_from_matrix(self, &rhs)
477  }
478}
479
480impl<'a, 'b, const R: usize, const C: usize> Sub<&'b Matrix<R, C>>
481  for &'a Matrix<R, C>
482{
483  type Output = Matrix<R, C>;
484
485  fn sub(
486    self,
487    rhs: &'b Matrix<R, C>,
488  ) -> Self::Output {
489    Matrix::subtract_matrix_from_matrix(self, rhs)
490  }
491}
492
493// Operator SubAssign ----------------------------------------------------------
494
495impl<const R: usize, const C: usize> SubAssign<f64> for Matrix<R, C> {
496  fn sub_assign(
497    &mut self,
498    rhs: f64,
499  ) {
500    self.subtract_scalar(rhs);
501  }
502}
503
504impl<const R: usize, const C: usize> SubAssign<f64> for &mut Matrix<R, C> {
505  fn sub_assign(
506    &mut self,
507    rhs: f64,
508  ) {
509    self.subtract_scalar(rhs);
510  }
511}
512
513impl<const R: usize, const C: usize> SubAssign<Matrix<R, C>> for Matrix<R, C> {
514  fn sub_assign(
515    &mut self,
516    rhs: Matrix<R, C>,
517  ) {
518    self.subtract_matrix(&rhs);
519  }
520}
521
522impl<const R: usize, const C: usize> SubAssign<Matrix<R, C>>
523  for &mut Matrix<R, C>
524{
525  fn sub_assign(
526    &mut self,
527    rhs: Matrix<R, C>,
528  ) {
529    self.subtract_matrix(&rhs);
530  }
531}
532
533impl<const R: usize, const C: usize> SubAssign<&Matrix<R, C>> for Matrix<R, C> {
534  fn sub_assign(
535    &mut self,
536    rhs: &Matrix<R, C>,
537  ) {
538    self.subtract_matrix(rhs);
539  }
540}
541
542impl<const R: usize, const C: usize> SubAssign<&Matrix<R, C>>
543  for &mut Matrix<R, C>
544{
545  fn sub_assign(
546    &mut self,
547    rhs: &Matrix<R, C>,
548  ) {
549    self.subtract_matrix(rhs);
550  }
551}