1use crate::matrices::iterators::{
28 ColumnReferenceIterator, RowMajorReferenceIterator, RowMajorReferenceMutIterator,
29 RowReferenceIterator,
30};
31use crate::matrices::views::{MatrixMut, MatrixRef, MatrixView, NoInteriorMutability};
32use crate::matrices::{Column, Matrix, Row};
33use crate::numeric::{Numeric, NumericRef};
34
35use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
36
37#[track_caller]
40#[inline]
41fn matrix_view_addition_iter<'l, 'r, T, S1, S2>(
42 left_iter: S1,
43 left_size: (Row, Column),
44 right_iter: S2,
45 right_size: (Row, Column),
46) -> Matrix<T>
47where
48 T: Numeric,
49 T: 'l,
50 T: 'r,
51 for<'a> &'a T: NumericRef<T>,
52 S1: Iterator<Item = &'l T>,
53 S2: Iterator<Item = &'r T>,
54{
55 assert!(
57 left_size == right_size,
58 "Mismatched matrices, left is {}x{}, right is {}x{}, + is only defined for MxN + MxN",
59 left_size.0,
60 left_size.1,
61 right_size.0,
62 right_size.1
63 );
64
65 let values = left_iter.zip(right_iter).map(|(x, y)| x + y).collect();
66 Matrix::from_flat_row_major(left_size, values)
67}
68
69#[track_caller]
70#[inline]
71fn matrix_view_subtraction_iter<'l, 'r, T, S1, S2>(
72 left_iter: S1,
73 left_size: (Row, Column),
74 right_iter: S2,
75 right_size: (Row, Column),
76) -> Matrix<T>
77where
78 T: Numeric,
79 T: 'l,
80 T: 'r,
81 for<'a> &'a T: NumericRef<T>,
82 S1: Iterator<Item = &'l T>,
83 S2: Iterator<Item = &'r T>,
84{
85 assert!(
87 left_size == right_size,
88 "Mismatched matrices, left is {}x{}, right is {}x{}, + is only defined for MxN + MxN",
89 left_size.0,
90 left_size.1,
91 right_size.0,
92 right_size.1
93 );
94
95 let values = left_iter.zip(right_iter).map(|(x, y)| x - y).collect();
96 Matrix::from_flat_row_major(left_size, values)
97}
98
99#[track_caller]
100#[inline]
101fn matrix_view_assign_addition_iter<'l, 'r, T, S1, S2>(
102 left_iter: S1,
103 left_size: (Row, Column),
104 right_iter: S2,
105 right_size: (Row, Column),
106) where
107 T: Numeric,
108 T: 'l,
109 T: 'r,
110 for<'a> &'a T: NumericRef<T>,
111 S1: Iterator<Item = &'l mut T>,
112 S2: Iterator<Item = &'r T>,
113{
114 assert!(
116 left_size == right_size,
117 "Mismatched matrices, left is {}x{}, right is {}x{}, += is only defined for MxN + MxN",
118 left_size.0,
119 left_size.1,
120 right_size.0,
121 right_size.1
122 );
123
124 for (x, y) in left_iter.zip(right_iter) {
125 *x = x.clone() + y;
129 }
130}
131
132#[track_caller]
133#[inline]
134fn matrix_view_assign_subtraction_iter<'l, 'r, T, S1, S2>(
135 left_iter: S1,
136 left_size: (Row, Column),
137 right_iter: S2,
138 right_size: (Row, Column),
139) where
140 T: Numeric,
141 T: 'l,
142 T: 'r,
143 for<'a> &'a T: NumericRef<T>,
144 S1: Iterator<Item = &'l mut T>,
145 S2: Iterator<Item = &'r T>,
146{
147 assert!(
149 left_size == right_size,
150 "Mismatched matrices, left is {}x{}, right is {}x{}, -= is only defined for MxN + MxN",
151 left_size.0,
152 left_size.1,
153 right_size.0,
154 right_size.1
155 );
156
157 for (x, y) in left_iter.zip(right_iter) {
158 *x = x.clone() - y;
162 }
163}
164
165#[track_caller]
166#[inline]
167fn matrix_view_multiplication<T, S1, S2>(left: &S1, right: &S2) -> Matrix<T>
168where
169 T: Numeric,
170 for<'a> &'a T: NumericRef<T>,
171 S1: MatrixRef<T> + NoInteriorMutability,
172 S2: MatrixRef<T> + NoInteriorMutability,
173{
174 use crate::tensors::operations::scalar_product;
175 assert!(
177 left.view_columns() == right.view_rows(),
178 "Mismatched Matrices, left is {}x{}, right is {}x{}, * is only defined for MxN * NxL",
179 left.view_rows(),
180 left.view_columns(),
181 right.view_rows(),
182 right.view_columns()
183 );
184
185 let mut result = Matrix::empty(T::zero(), (left.view_rows(), right.view_columns()));
186
187 for ((i, j), x) in result.row_major_reference_mut_iter().with_index() {
188 let left = RowReferenceIterator::from(left, i);
190 let right = ColumnReferenceIterator::from(right, j);
192 *x = scalar_product::<T, _, _>(left, right);
194 }
195 result
196}
197
198macro_rules! matrix_view_reference_matrix_view_reference_operation {
199 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
200 #[doc=$doc]
201 impl<T, S1, S2> $op<&MatrixView<T, S2>> for &MatrixView<T, S1>
202 where
203 T: Numeric,
204 for<'a> &'a T: NumericRef<T>,
205 S1: MatrixRef<T> + NoInteriorMutability,
206 S2: MatrixRef<T> + NoInteriorMutability,
207 {
208 type Output = Matrix<T>;
209
210 #[track_caller]
211 #[inline]
212 fn $method(self, rhs: &MatrixView<T, S2>) -> Self::Output {
213 $implementation::<T, S1, S2>(self.source_ref(), rhs.source_ref())
214 }
215 }
216 };
217}
218
219macro_rules! matrix_view_reference_matrix_view_reference_operation_iter {
220 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
221 #[doc=$doc]
222 impl<T, S1, S2> $op<&MatrixView<T, S2>> for &MatrixView<T, S1>
223 where
224 T: Numeric,
225 for<'a> &'a T: NumericRef<T>,
226 S1: MatrixRef<T> + NoInteriorMutability,
227 S2: MatrixRef<T> + NoInteriorMutability,
228 {
229 type Output = Matrix<T>;
230
231 #[track_caller]
232 #[inline]
233 fn $method(self, rhs: &MatrixView<T, S2>) -> Self::Output {
234 $implementation::<T, _, _>(
235 RowMajorReferenceIterator::from(self.source_ref()),
236 self.size(),
237 RowMajorReferenceIterator::from(rhs.source_ref()),
238 rhs.size(),
239 )
240 }
241 }
242 };
243}
244
245matrix_view_reference_matrix_view_reference_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for two referenced matrix views");
246matrix_view_reference_matrix_view_reference_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two referenced matrix views");
247matrix_view_reference_matrix_view_reference_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for two referenced matrix views");
248
249macro_rules! matrix_view_assign_matrix_view_reference_operation_iter {
250 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
251 #[doc=$doc]
252 impl<T, S1, S2> $op<&MatrixView<T, S2>> for MatrixView<T, S1>
253 where
254 T: Numeric,
255 for<'a> &'a T: NumericRef<T>,
256 S1: MatrixMut<T> + NoInteriorMutability,
257 S2: MatrixRef<T> + NoInteriorMutability,
258 {
259 #[track_caller]
260 #[inline]
261 fn $method(&mut self, rhs: &MatrixView<T, S2>) {
262 let left_size = self.size();
263 $implementation::<T, _, _>(
264 RowMajorReferenceMutIterator::from(self.source_ref_mut()),
265 left_size,
266 RowMajorReferenceIterator::from(rhs.source_ref()),
267 rhs.size(),
268 )
269 }
270 }
271 };
272}
273
274matrix_view_assign_matrix_view_reference_operation_iter!(impl AddAssign for MatrixView { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for two referenced matrix views");
275matrix_view_assign_matrix_view_reference_operation_iter!(impl SubAssign for MatrixView { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for two referenced matrix views");
276
277macro_rules! matrix_view_reference_matrix_view_value_operation {
278 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
279 #[doc=$doc]
280 impl<T, S1, S2> $op<MatrixView<T, S2>> for &MatrixView<T, S1>
281 where
282 T: Numeric,
283 for<'a> &'a T: NumericRef<T>,
284 S1: MatrixRef<T> + NoInteriorMutability,
285 S2: MatrixRef<T> + NoInteriorMutability,
286 {
287 type Output = Matrix<T>;
288
289 #[track_caller]
290 #[inline]
291 fn $method(self, rhs: MatrixView<T, S2>) -> Self::Output {
292 $implementation::<T, S1, S2>(self.source_ref(), rhs.source_ref())
293 }
294 }
295 };
296}
297
298macro_rules! matrix_view_reference_matrix_view_value_operation_iter {
299 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
300 #[doc=$doc]
301 impl<T, S1, S2> $op<MatrixView<T, S2>> for &MatrixView<T, S1>
302 where
303 T: Numeric,
304 for<'a> &'a T: NumericRef<T>,
305 S1: MatrixRef<T> + NoInteriorMutability,
306 S2: MatrixRef<T> + NoInteriorMutability,
307 {
308 type Output = Matrix<T>;
309
310 #[track_caller]
311 #[inline]
312 fn $method(self, rhs: MatrixView<T, S2>) -> Self::Output {
313 $implementation::<T, _, _>(
314 RowMajorReferenceIterator::from(self.source_ref()),
315 self.size(),
316 RowMajorReferenceIterator::from(rhs.source_ref()),
317 rhs.size(),
318 )
319 }
320 }
321 };
322}
323
324matrix_view_reference_matrix_view_value_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for two matrix views with one referenced");
325matrix_view_reference_matrix_view_value_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two matrix views with one referenced");
326matrix_view_reference_matrix_view_value_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for two matrix views with one referenced");
327
328macro_rules! matrix_view_assign_matrix_view_value_operation_iter {
329 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
330 #[doc=$doc]
331 impl<T, S1, S2> $op<MatrixView<T, S2>> for MatrixView<T, S1>
332 where
333 T: Numeric,
334 for<'a> &'a T: NumericRef<T>,
335 S1: MatrixMut<T> + NoInteriorMutability,
336 S2: MatrixRef<T> + NoInteriorMutability,
337 {
338 #[track_caller]
339 #[inline]
340 fn $method(&mut self, rhs: MatrixView<T, S2>) {
341 let left_size = self.size();
342 $implementation::<T, _, _>(
343 RowMajorReferenceMutIterator::from(self.source_ref_mut()),
344 left_size,
345 RowMajorReferenceIterator::from(rhs.source_ref()),
346 rhs.size(),
347 )
348 }
349 }
350 };
351}
352
353matrix_view_assign_matrix_view_value_operation_iter!(impl AddAssign for MatrixView { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for two matrix views with one referenced");
354matrix_view_assign_matrix_view_value_operation_iter!(impl SubAssign for MatrixView { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for two matrix views with one referenced");
355
356macro_rules! matrix_view_value_matrix_view_reference_operation {
357 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
358 #[doc=$doc]
359 impl<T, S1, S2> $op<&MatrixView<T, S2>> for MatrixView<T, S1>
360 where
361 T: Numeric,
362 for<'a> &'a T: NumericRef<T>,
363 S1: MatrixRef<T> + NoInteriorMutability,
364 S2: MatrixRef<T> + NoInteriorMutability,
365 {
366 type Output = Matrix<T>;
367
368 #[track_caller]
369 #[inline]
370 fn $method(self, rhs: &MatrixView<T, S2>) -> Self::Output {
371 $implementation::<T, S1, S2>(self.source_ref(), rhs.source_ref())
372 }
373 }
374 };
375}
376
377macro_rules! matrix_view_value_matrix_view_reference_operation_iter {
378 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
379 #[doc=$doc]
380 impl<T, S1, S2> $op<&MatrixView<T, S2>> for MatrixView<T, S1>
381 where
382 T: Numeric,
383 for<'a> &'a T: NumericRef<T>,
384 S1: MatrixRef<T> + NoInteriorMutability,
385 S2: MatrixRef<T> + NoInteriorMutability,
386 {
387 type Output = Matrix<T>;
388
389 #[track_caller]
390 #[inline]
391 fn $method(self, rhs: &MatrixView<T, S2>) -> Self::Output {
392 $implementation::<T, _, _>(
393 RowMajorReferenceIterator::from(self.source_ref()),
394 self.size(),
395 RowMajorReferenceIterator::from(rhs.source_ref()),
396 rhs.size(),
397 )
398 }
399 }
400 };
401}
402
403matrix_view_value_matrix_view_reference_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for two matrix views with one referenced");
404matrix_view_value_matrix_view_reference_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise addition for two matrix views with one referenced");
405matrix_view_value_matrix_view_reference_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for two matrix views with one referenced");
406
407macro_rules! matrix_view_value_matrix_view_value_operation {
408 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
409 #[doc=$doc]
410 impl<T, S1, S2> $op<MatrixView<T, S2>> for MatrixView<T, S1>
411 where
412 T: Numeric,
413 for<'a> &'a T: NumericRef<T>,
414 S1: MatrixRef<T> + NoInteriorMutability,
415 S2: MatrixRef<T> + NoInteriorMutability,
416 {
417 type Output = Matrix<T>;
418
419 #[track_caller]
420 #[inline]
421 fn $method(self, rhs: MatrixView<T, S2>) -> Self::Output {
422 $implementation::<T, S1, S2>(self.source_ref(), rhs.source_ref())
423 }
424 }
425 };
426}
427
428macro_rules! matrix_view_value_matrix_view_value_operation_iter {
429 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
430 #[doc=$doc]
431 impl<T, S1, S2> $op<MatrixView<T, S2>> for MatrixView<T, S1>
432 where
433 T: Numeric,
434 for<'a> &'a T: NumericRef<T>,
435 S1: MatrixRef<T> + NoInteriorMutability,
436 S2: MatrixRef<T> + NoInteriorMutability,
437 {
438 type Output = Matrix<T>;
439
440 #[track_caller]
441 #[inline]
442 fn $method(self, rhs: MatrixView<T, S2>) -> Self::Output {
443 $implementation::<T, _, _>(
444 RowMajorReferenceIterator::from(self.source_ref()),
445 self.size(),
446 RowMajorReferenceIterator::from(rhs.source_ref()),
447 rhs.size(),
448 )
449 }
450 }
451 };
452}
453
454matrix_view_value_matrix_view_value_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for two matrix views");
455matrix_view_value_matrix_view_value_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two matrix views");
456matrix_view_value_matrix_view_value_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for two matrix views");
457
458macro_rules! matrix_view_reference_matrix_reference_operation {
459 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
460 #[doc=$doc]
461 impl<T, S> $op<&Matrix<T>> for &MatrixView<T, S>
462 where
463 T: Numeric,
464 for<'a> &'a T: NumericRef<T>,
465 S: MatrixRef<T> + NoInteriorMutability,
466 {
467 type Output = Matrix<T>;
468
469 #[track_caller]
470 #[inline]
471 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
472 $implementation::<T, S, Matrix<T>>(self.source_ref(), rhs)
473 }
474 }
475 };
476}
477
478macro_rules! matrix_view_reference_matrix_reference_operation_iter {
479 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
480 #[doc=$doc]
481 impl<T, S> $op<&Matrix<T>> for &MatrixView<T, S>
482 where
483 T: Numeric,
484 for<'a> &'a T: NumericRef<T>,
485 S: MatrixRef<T> + NoInteriorMutability,
486 {
487 type Output = Matrix<T>;
488
489 #[track_caller]
490 #[inline]
491 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
492 $implementation::<T, _, _>(
493 RowMajorReferenceIterator::from(self.source_ref()),
494 self.size(),
495 rhs.direct_row_major_reference_iter(),
496 rhs.size(),
497 )
498 }
499 }
500 };
501}
502
503matrix_view_reference_matrix_reference_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for a referenced matrix view and a referenced matrix");
504matrix_view_reference_matrix_reference_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a referenced matrix view and a referenced matrix");
505matrix_view_reference_matrix_reference_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for a referenced matrix view and a referenced matrix");
506
507macro_rules! matrix_view_assign_matrix_reference_operation_iter {
508 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
509 #[doc=$doc]
510 impl<T, S> $op<&Matrix<T>> for MatrixView<T, S>
511 where
512 T: Numeric,
513 for<'a> &'a T: NumericRef<T>,
514 S: MatrixMut<T> + NoInteriorMutability,
515 {
516 #[track_caller]
517 #[inline]
518 fn $method(&mut self, rhs: &Matrix<T>) {
519 let left_size = self.size();
520 $implementation::<T, _, _>(
521 RowMajorReferenceMutIterator::from(self.source_ref_mut()),
522 left_size,
523 rhs.direct_row_major_reference_iter(),
524 rhs.size(),
525 )
526 }
527 }
528 };
529}
530
531matrix_view_assign_matrix_reference_operation_iter!(impl AddAssign for MatrixView { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for a referenced matrix view and a referenced matrix");
532matrix_view_assign_matrix_reference_operation_iter!(impl SubAssign for MatrixView { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for a referenced matrix view and a referenced matrix");
533
534macro_rules! matrix_view_reference_matrix_value_operation {
535 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
536 #[doc=$doc]
537 impl<T, S> $op<Matrix<T>> for &MatrixView<T, S>
538 where
539 T: Numeric,
540 for<'a> &'a T: NumericRef<T>,
541 S: MatrixRef<T> + NoInteriorMutability,
542 {
543 type Output = Matrix<T>;
544
545 #[track_caller]
546 #[inline]
547 fn $method(self, rhs: Matrix<T>) -> Self::Output {
548 $implementation::<T, S, Matrix<T>>(self.source_ref(), &rhs)
549 }
550 }
551 };
552}
553
554macro_rules! matrix_view_reference_matrix_value_operation_iter {
555 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
556 #[doc=$doc]
557 impl<T, S> $op<Matrix<T>> for &MatrixView<T, S>
558 where
559 T: Numeric,
560 for<'a> &'a T: NumericRef<T>,
561 S: MatrixRef<T> + NoInteriorMutability,
562 {
563 type Output = Matrix<T>;
564
565 #[track_caller]
566 #[inline]
567 fn $method(self, rhs: Matrix<T>) -> Self::Output {
568 $implementation::<T, _, _>(
569 RowMajorReferenceIterator::from(self.source_ref()),
570 self.size(),
571 rhs.direct_row_major_reference_iter(),
572 rhs.size(),
573 )
574 }
575 }
576 };
577}
578
579matrix_view_reference_matrix_value_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for a referenced matrix view and a matrix");
580matrix_view_reference_matrix_value_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a referenced matrix view and a matrix");
581matrix_view_reference_matrix_value_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for a referenced matrix view and a matrix");
582
583macro_rules! matrix_view_assign_matrix_value_operation_iter {
584 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
585 #[doc=$doc]
586 impl<T, S> $op<Matrix<T>> for MatrixView<T, S>
587 where
588 T: Numeric,
589 for<'a> &'a T: NumericRef<T>,
590 S: MatrixMut<T> + NoInteriorMutability,
591 {
592 #[track_caller]
593 #[inline]
594 fn $method(&mut self, rhs: Matrix<T>) {
595 let left_size = self.size();
596 $implementation::<T, _, _>(
597 RowMajorReferenceMutIterator::from(self.source_ref_mut()),
598 left_size,
599 rhs.direct_row_major_reference_iter(),
600 rhs.size(),
601 )
602 }
603 }
604 };
605}
606
607matrix_view_assign_matrix_value_operation_iter!(impl AddAssign for MatrixView { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for a referenced matrix view and a matrix");
608matrix_view_assign_matrix_value_operation_iter!(impl SubAssign for MatrixView { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for a referenced matrix view and a matrix");
609
610macro_rules! matrix_view_value_matrix_reference_operation {
611 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
612 #[doc=$doc]
613 impl<T, S> $op<&Matrix<T>> for MatrixView<T, S>
614 where
615 T: Numeric,
616 for<'a> &'a T: NumericRef<T>,
617 S: MatrixRef<T> + NoInteriorMutability,
618 {
619 type Output = Matrix<T>;
620
621 #[track_caller]
622 #[inline]
623 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
624 $implementation::<T, S, Matrix<T>>(self.source_ref(), rhs)
625 }
626 }
627 };
628}
629
630macro_rules! matrix_view_value_matrix_reference_operation_iter {
631 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
632 #[doc=$doc]
633 impl<T, S> $op<&Matrix<T>> for MatrixView<T, S>
634 where
635 T: Numeric,
636 for<'a> &'a T: NumericRef<T>,
637 S: MatrixRef<T> + NoInteriorMutability,
638 {
639 type Output = Matrix<T>;
640
641 #[track_caller]
642 #[inline]
643 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
644 $implementation::<T, _, _>(
645 RowMajorReferenceIterator::from(self.source_ref()),
646 self.size(),
647 rhs.direct_row_major_reference_iter(),
648 rhs.size(),
649 )
650 }
651 }
652 };
653}
654
655matrix_view_value_matrix_reference_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for a matrix view and a referenced matrix");
656matrix_view_value_matrix_reference_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a matrix view and a referenced matrix");
657matrix_view_value_matrix_reference_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for a matrix view and a referenced matrix");
658
659macro_rules! matrix_view_value_matrix_value_operation {
660 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
661 #[doc=$doc]
662 impl<T, S> $op<Matrix<T>> for MatrixView<T, S>
663 where
664 T: Numeric,
665 for<'a> &'a T: NumericRef<T>,
666 S: MatrixRef<T> + NoInteriorMutability,
667 {
668 type Output = Matrix<T>;
669
670 #[track_caller]
671 #[inline]
672 fn $method(self, rhs: Matrix<T>) -> Self::Output {
673 $implementation::<T, S, Matrix<T>>(self.source_ref(), &rhs)
674 }
675 }
676 };
677}
678
679macro_rules! matrix_view_value_matrix_value_operation_iter {
680 (impl $op:tt for MatrixView { fn $method:ident } $implementation:ident $doc:tt) => {
681 #[doc=$doc]
682 impl<T, S> $op<Matrix<T>> for MatrixView<T, S>
683 where
684 T: Numeric,
685 for<'a> &'a T: NumericRef<T>,
686 S: MatrixRef<T> + NoInteriorMutability,
687 {
688 type Output = Matrix<T>;
689
690 #[track_caller]
691 #[inline]
692 fn $method(self, rhs: Matrix<T>) -> Self::Output {
693 $implementation::<T, _, _>(
694 RowMajorReferenceIterator::from(self.source_ref()),
695 self.size(),
696 rhs.direct_row_major_reference_iter(),
697 rhs.size(),
698 )
699 }
700 }
701 };
702}
703
704matrix_view_value_matrix_value_operation_iter!(impl Add for MatrixView { fn add } matrix_view_addition_iter "Elementwise addition for a matrix view and a matrix");
705matrix_view_value_matrix_value_operation_iter!(impl Sub for MatrixView { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a matrix view and a matrix");
706matrix_view_value_matrix_value_operation!(impl Mul for MatrixView { fn mul } matrix_view_multiplication "Matrix multiplication for a matrix view and a matrix");
707
708macro_rules! matrix_reference_matrix_view_reference_operation {
709 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
710 #[doc=$doc]
711 impl<T, S> $op<&MatrixView<T, S>> for &Matrix<T>
712 where
713 T: Numeric,
714 for<'a> &'a T: NumericRef<T>,
715 S: MatrixRef<T> + NoInteriorMutability,
716 {
717 type Output = Matrix<T>;
718
719 #[track_caller]
720 #[inline]
721 fn $method(self, rhs: &MatrixView<T, S>) -> Self::Output {
722 $implementation::<T, Matrix<T>, S>(self, rhs.source_ref())
723 }
724 }
725 };
726}
727
728macro_rules! matrix_reference_matrix_view_reference_operation_iter {
729 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
730 #[doc=$doc]
731 impl<T, S> $op<&MatrixView<T, S>> for &Matrix<T>
732 where
733 T: Numeric,
734 for<'a> &'a T: NumericRef<T>,
735 S: MatrixRef<T> + NoInteriorMutability,
736 {
737 type Output = Matrix<T>;
738
739 #[track_caller]
740 #[inline]
741 fn $method(self, rhs: &MatrixView<T, S>) -> Self::Output {
742 $implementation::<T, _, _>(
743 self.direct_row_major_reference_iter(),
744 self.size(),
745 RowMajorReferenceIterator::from(rhs.source_ref()),
746 rhs.size(),
747 )
748 }
749 }
750 };
751}
752
753matrix_reference_matrix_view_reference_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for a referenced matrix and a referenced matrix view");
754matrix_reference_matrix_view_reference_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a referenced matrix and a referenced matrix view");
755matrix_reference_matrix_view_reference_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for a referenced matrix and a referenced matrix view");
756
757macro_rules! matrix_assign_matrix_view_reference_operation_iter {
758 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
759 #[doc=$doc]
760 impl<T, S> $op<&MatrixView<T, S>> for Matrix<T>
761 where
762 T: Numeric,
763 for<'a> &'a T: NumericRef<T>,
764 S: MatrixRef<T> + NoInteriorMutability,
765 {
766 #[track_caller]
767 #[inline]
768 fn $method(&mut self, rhs: &MatrixView<T, S>) {
769 let left_size = self.size();
770 $implementation::<T, _, _>(
771 self.direct_row_major_reference_iter_mut(),
772 left_size,
773 RowMajorReferenceIterator::from(rhs.source_ref()),
774 rhs.size(),
775 )
776 }
777 }
778 };
779}
780
781matrix_assign_matrix_view_reference_operation_iter!(impl AddAssign for Matrix { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for a referenced matrix and a referenced matrix view");
782matrix_assign_matrix_view_reference_operation_iter!(impl SubAssign for Matrix { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for a referenced matrix and a referenced matrix view");
783
784macro_rules! matrix_reference_matrix_view_value_operation {
785 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
786 #[doc=$doc]
787 impl<T, S> $op<MatrixView<T, S>> for &Matrix<T>
788 where
789 T: Numeric,
790 for<'a> &'a T: NumericRef<T>,
791 S: MatrixRef<T> + NoInteriorMutability,
792 {
793 type Output = Matrix<T>;
794
795 #[track_caller]
796 #[inline]
797 fn $method(self, rhs: MatrixView<T, S>) -> Self::Output {
798 $implementation::<T, Matrix<T>, S>(self, rhs.source_ref())
799 }
800 }
801 };
802}
803
804macro_rules! matrix_reference_matrix_view_value_operation_iter {
805 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
806 #[doc=$doc]
807 impl<T, S> $op<MatrixView<T, S>> for &Matrix<T>
808 where
809 T: Numeric,
810 for<'a> &'a T: NumericRef<T>,
811 S: MatrixRef<T> + NoInteriorMutability,
812 {
813 type Output = Matrix<T>;
814
815 #[track_caller]
816 #[inline]
817 fn $method(self, rhs: MatrixView<T, S>) -> Self::Output {
818 $implementation::<T, _, _>(
819 self.direct_row_major_reference_iter(),
820 self.size(),
821 RowMajorReferenceIterator::from(rhs.source_ref()),
822 rhs.size(),
823 )
824 }
825 }
826 };
827}
828
829matrix_reference_matrix_view_value_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for a referenced matrix and a matrix view");
830matrix_reference_matrix_view_value_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a referenced matrix and a matrix view");
831matrix_reference_matrix_view_value_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for a referenced matrix and a matrix view");
832
833macro_rules! matrix_assign_matrix_view_value_operation_iter {
834 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
835 #[doc=$doc]
836 impl<T, S> $op<MatrixView<T, S>> for Matrix<T>
837 where
838 T: Numeric,
839 for<'a> &'a T: NumericRef<T>,
840 S: MatrixRef<T> + NoInteriorMutability,
841 {
842 #[track_caller]
843 #[inline]
844 fn $method(&mut self, rhs: MatrixView<T, S>) {
845 let left_size = self.size();
846 $implementation::<T, _, _>(
847 self.direct_row_major_reference_iter_mut(),
848 left_size,
849 RowMajorReferenceIterator::from(rhs.source_ref()),
850 rhs.size(),
851 )
852 }
853 }
854 };
855}
856
857matrix_assign_matrix_view_value_operation_iter!(impl AddAssign for Matrix { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for a referenced matrix and a matrix view");
858matrix_assign_matrix_view_value_operation_iter!(impl SubAssign for Matrix { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for a referenced matrix and a matrix view");
859
860macro_rules! matrix_value_matrix_view_reference_operation {
861 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
862 #[doc=$doc]
863 impl<T, S> $op<&MatrixView<T, S>> for Matrix<T>
864 where
865 T: Numeric,
866 for<'a> &'a T: NumericRef<T>,
867 S: MatrixRef<T> + NoInteriorMutability,
868 {
869 type Output = Matrix<T>;
870
871 #[track_caller]
872 #[inline]
873 fn $method(self, rhs: &MatrixView<T, S>) -> Self::Output {
874 $implementation::<T, Matrix<T>, S>(&self, rhs.source_ref())
875 }
876 }
877 };
878}
879
880macro_rules! matrix_value_matrix_view_reference_operation_iter {
881 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
882 #[doc=$doc]
883 impl<T, S> $op<&MatrixView<T, S>> for Matrix<T>
884 where
885 T: Numeric,
886 for<'a> &'a T: NumericRef<T>,
887 S: MatrixRef<T> + NoInteriorMutability,
888 {
889 type Output = Matrix<T>;
890
891 #[track_caller]
892 #[inline]
893 fn $method(self, rhs: &MatrixView<T, S>) -> Self::Output {
894 $implementation::<T, _, _>(
895 self.direct_row_major_reference_iter(),
896 self.size(),
897 RowMajorReferenceIterator::from(rhs.source_ref()),
898 rhs.size(),
899 )
900 }
901 }
902 };
903}
904
905matrix_value_matrix_view_reference_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for a matrix and a referenced matrix view");
906matrix_value_matrix_view_reference_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a matrix and a referenced matrix view");
907matrix_value_matrix_view_reference_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for a matrix and a referenced matrix view");
908
909macro_rules! matrix_value_matrix_view_value_operation {
910 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
911 #[doc=$doc]
912 impl<T, S> $op<MatrixView<T, S>> for Matrix<T>
913 where
914 T: Numeric,
915 for<'a> &'a T: NumericRef<T>,
916 S: MatrixRef<T> + NoInteriorMutability,
917 {
918 type Output = Matrix<T>;
919
920 #[track_caller]
921 #[inline]
922 fn $method(self, rhs: MatrixView<T, S>) -> Self::Output {
923 $implementation::<T, Matrix<T>, S>(&self, rhs.source_ref())
924 }
925 }
926 };
927}
928
929macro_rules! matrix_value_matrix_view_value_operation_iter {
930 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
931 #[doc=$doc]
932 impl<T, S> $op<MatrixView<T, S>> for Matrix<T>
933 where
934 T: Numeric,
935 for<'a> &'a T: NumericRef<T>,
936 S: MatrixRef<T> + NoInteriorMutability,
937 {
938 type Output = Matrix<T>;
939
940 #[track_caller]
941 #[inline]
942 fn $method(self, rhs: MatrixView<T, S>) -> Self::Output {
943 $implementation::<T, _, _>(
944 self.direct_row_major_reference_iter(),
945 self.size(),
946 RowMajorReferenceIterator::from(rhs.source_ref()),
947 rhs.size(),
948 )
949 }
950 }
951 };
952}
953
954matrix_value_matrix_view_value_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for a matrix and a matrix view");
955matrix_value_matrix_view_value_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for a matrix and a matrix view");
956matrix_value_matrix_view_value_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for a matrix and a matrix view");
957
958macro_rules! matrix_reference_matrix_reference_operation {
959 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
960 #[doc=$doc]
961 impl<T> $op<&Matrix<T>> for &Matrix<T>
962 where
963 T: Numeric,
964 for<'a> &'a T: NumericRef<T>,
965 {
966 type Output = Matrix<T>;
967
968 #[track_caller]
969 #[inline]
970 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
971 $implementation::<T, Matrix<T>, Matrix<T>>(self, rhs)
972 }
973 }
974 };
975}
976
977macro_rules! matrix_reference_matrix_reference_operation_iter {
978 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
979 #[doc=$doc]
980 impl<T> $op<&Matrix<T>> for &Matrix<T>
981 where
982 T: Numeric,
983 for<'a> &'a T: NumericRef<T>,
984 {
985 type Output = Matrix<T>;
986
987 #[track_caller]
988 #[inline]
989 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
990 $implementation::<T, _, _>(
991 self.direct_row_major_reference_iter(),
992 self.size(),
993 rhs.direct_row_major_reference_iter(),
994 rhs.size(),
995 )
996 }
997 }
998 };
999}
1000
1001matrix_reference_matrix_reference_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for two referenced matrices");
1002matrix_reference_matrix_reference_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two referenced matrices");
1003matrix_reference_matrix_reference_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for two referenced matrices");
1004
1005macro_rules! matrix_assign_matrix_reference_operation_iter {
1006 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1007 #[doc=$doc]
1008 impl<T> $op<&Matrix<T>> for Matrix<T>
1009 where
1010 T: Numeric,
1011 for<'a> &'a T: NumericRef<T>,
1012 {
1013 #[track_caller]
1014 #[inline]
1015 fn $method(&mut self, rhs: &Matrix<T>) {
1016 let left_size = self.size();
1017 $implementation::<T, _, _>(
1018 self.direct_row_major_reference_iter_mut(),
1019 left_size,
1020 rhs.direct_row_major_reference_iter(),
1021 rhs.size(),
1022 )
1023 }
1024 }
1025 };
1026}
1027
1028matrix_assign_matrix_reference_operation_iter!(impl AddAssign for Matrix { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for two referenced matrices");
1029matrix_assign_matrix_reference_operation_iter!(impl SubAssign for Matrix { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for two referenced matrices");
1030
1031macro_rules! matrix_reference_matrix_value_operation {
1032 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1033 #[doc=$doc]
1034 impl<T> $op<Matrix<T>> for &Matrix<T>
1035 where
1036 T: Numeric,
1037 for<'a> &'a T: NumericRef<T>,
1038 {
1039 type Output = Matrix<T>;
1040
1041 #[track_caller]
1042 #[inline]
1043 fn $method(self, rhs: Matrix<T>) -> Self::Output {
1044 $implementation::<T, Matrix<T>, Matrix<T>>(self, &rhs)
1045 }
1046 }
1047 };
1048}
1049
1050macro_rules! matrix_reference_matrix_value_operation_iter {
1051 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1052 #[doc=$doc]
1053 impl<T> $op<Matrix<T>> for &Matrix<T>
1054 where
1055 T: Numeric,
1056 for<'a> &'a T: NumericRef<T>,
1057 {
1058 type Output = Matrix<T>;
1059
1060 #[track_caller]
1061 #[inline]
1062 fn $method(self, rhs: Matrix<T>) -> Self::Output {
1063 $implementation::<T, _, _>(
1064 self.direct_row_major_reference_iter(),
1065 self.size(),
1066 rhs.direct_row_major_reference_iter(),
1067 rhs.size(),
1068 )
1069 }
1070 }
1071 };
1072}
1073
1074matrix_reference_matrix_value_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for two matrices with one referenced");
1075matrix_reference_matrix_value_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two matrices with one referenced");
1076matrix_reference_matrix_value_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for two matrices with one referenced");
1077
1078macro_rules! matrix_assign_matrix_value_operation_iter {
1079 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1080 #[doc=$doc]
1081 impl<T> $op<Matrix<T>> for Matrix<T>
1082 where
1083 T: Numeric,
1084 for<'a> &'a T: NumericRef<T>,
1085 {
1086 #[track_caller]
1087 #[inline]
1088 fn $method(&mut self, rhs: Matrix<T>) {
1089 let left_size = self.size();
1090 $implementation::<T, _, _>(
1091 self.direct_row_major_reference_iter_mut(),
1092 left_size,
1093 rhs.direct_row_major_reference_iter(),
1094 rhs.size(),
1095 )
1096 }
1097 }
1098 };
1099}
1100
1101matrix_assign_matrix_value_operation_iter!(impl AddAssign for Matrix { fn add_assign } matrix_view_assign_addition_iter "Elementwise assigning addition for two matrices with one referenced");
1102matrix_assign_matrix_value_operation_iter!(impl SubAssign for Matrix { fn sub_assign } matrix_view_assign_subtraction_iter "Elementwise assigning subtraction for two matrices with one referenced");
1103
1104macro_rules! matrix_value_matrix_reference_operation {
1105 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1106 #[doc=$doc]
1107 impl<T> $op<&Matrix<T>> for Matrix<T>
1108 where
1109 T: Numeric,
1110 for<'a> &'a T: NumericRef<T>,
1111 {
1112 type Output = Matrix<T>;
1113
1114 #[track_caller]
1115 #[inline]
1116 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
1117 $implementation::<T, Matrix<T>, Matrix<T>>(&self, rhs)
1118 }
1119 }
1120 };
1121}
1122
1123macro_rules! matrix_value_matrix_reference_operation_iter {
1124 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1125 #[doc=$doc]
1126 impl<T> $op<&Matrix<T>> for Matrix<T>
1127 where
1128 T: Numeric,
1129 for<'a> &'a T: NumericRef<T>,
1130 {
1131 type Output = Matrix<T>;
1132
1133 #[track_caller]
1134 #[inline]
1135 fn $method(self, rhs: &Matrix<T>) -> Self::Output {
1136 $implementation::<T, _, _>(
1137 self.direct_row_major_reference_iter(),
1138 self.size(),
1139 rhs.direct_row_major_reference_iter(),
1140 rhs.size(),
1141 )
1142 }
1143 }
1144 };
1145}
1146
1147matrix_value_matrix_reference_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for two matrices with one referenced");
1148matrix_value_matrix_reference_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two matrices with one referenced");
1149matrix_value_matrix_reference_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for two matrices with one referenced");
1150
1151macro_rules! matrix_value_matrix_value_operation {
1152 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1153 #[doc=$doc]
1154 impl<T> $op<Matrix<T>> for Matrix<T>
1155 where
1156 T: Numeric,
1157 for<'a> &'a T: NumericRef<T>,
1158 {
1159 type Output = Matrix<T>;
1160
1161 #[track_caller]
1162 #[inline]
1163 fn $method(self, rhs: Matrix<T>) -> Self::Output {
1164 $implementation::<T, Matrix<T>, Matrix<T>>(&self, &rhs)
1165 }
1166 }
1167 };
1168}
1169
1170macro_rules! matrix_value_matrix_value_operation_iter {
1171 (impl $op:tt for Matrix { fn $method:ident } $implementation:ident $doc:tt) => {
1172 #[doc=$doc]
1173 impl<T> $op<Matrix<T>> for Matrix<T>
1174 where
1175 T: Numeric,
1176 for<'a> &'a T: NumericRef<T>,
1177 {
1178 type Output = Matrix<T>;
1179
1180 #[track_caller]
1181 #[inline]
1182 fn $method(self, rhs: Matrix<T>) -> Self::Output {
1183 $implementation::<T, _, _>(
1184 self.direct_row_major_reference_iter(),
1185 self.size(),
1186 rhs.direct_row_major_reference_iter(),
1187 rhs.size(),
1188 )
1189 }
1190 }
1191 };
1192}
1193
1194matrix_value_matrix_value_operation_iter!(impl Add for Matrix { fn add } matrix_view_addition_iter "Elementwise addition for two matrices");
1195matrix_value_matrix_value_operation_iter!(impl Sub for Matrix { fn sub } matrix_view_subtraction_iter "Elementwise subtraction for two matrices");
1196matrix_value_matrix_value_operation!(impl Mul for Matrix { fn mul } matrix_view_multiplication "Matrix multiplication for two matrices");
1197
1198#[test]
1199fn test_all_16_combinations() {
1200 fn matrix() -> Matrix<i8> {
1201 Matrix::from_scalar(1)
1202 }
1203 fn matrix_view() -> MatrixView<i8, Matrix<i8>> {
1204 MatrixView::from(Matrix::from_scalar(1))
1205 }
1206 let mut results = Vec::with_capacity(16);
1207 results.push(matrix() + matrix());
1208 results.push(matrix() + &matrix());
1209 results.push(&matrix() + matrix());
1210 results.push(&matrix() + &matrix());
1211 results.push(matrix_view() + matrix());
1212 results.push(matrix_view() + &matrix());
1213 results.push(&matrix_view() + matrix());
1214 results.push(&matrix_view() + &matrix());
1215 results.push(matrix() + matrix_view());
1216 results.push(matrix() + &matrix_view());
1217 results.push(&matrix() + matrix_view());
1218 results.push(&matrix() + &matrix_view());
1219 results.push(matrix_view() + matrix_view());
1220 results.push(matrix_view() + &matrix_view());
1221 results.push(&matrix_view() + matrix_view());
1222 results.push(&matrix_view() + &matrix_view());
1223 for total in results {
1224 assert_eq!(total.scalar(), 2);
1225 }
1226}
1227
1228#[test]
1229fn elementwise_addition_assign_test_all_8_combinations() {
1230 fn matrix() -> Matrix<i8> {
1231 Matrix::from_scalar(1)
1232 }
1233 fn matrix_view() -> MatrixView<i8, Matrix<i8>> {
1234 MatrixView::from(Matrix::from_scalar(1))
1235 }
1236 let mut results_matrix = Vec::with_capacity(16);
1237 let mut results_matrix_views = Vec::with_capacity(16);
1238 results_matrix.push({
1239 let mut x = matrix();
1240 x += matrix();
1241 x
1242 });
1243 results_matrix.push({
1244 let mut x = matrix();
1245 x += &matrix();
1246 x
1247 });
1248 results_matrix_views.push({
1249 let mut x = matrix_view();
1250 x += matrix();
1251 x
1252 });
1253 results_matrix_views.push({
1254 let mut x = matrix_view();
1255 x += &matrix();
1256 x
1257 });
1258 results_matrix.push({
1259 let mut x = matrix();
1260 x += matrix_view();
1261 x
1262 });
1263 results_matrix.push({
1264 let mut x = matrix();
1265 x += &matrix_view();
1266 x
1267 });
1268 results_matrix_views.push({
1269 let mut x = matrix_view();
1270 x += matrix_view();
1271 x
1272 });
1273 results_matrix_views.push({
1274 let mut x = matrix_view();
1275 x += &matrix_view();
1276 x
1277 });
1278 for total in results_matrix {
1279 assert_eq!(total.scalar(), 2);
1280 }
1281 for total in results_matrix_views {
1282 assert_eq!(total.get(0, 0), 2);
1283 }
1284}
1285
1286#[test]
1287fn elementwise_subtraction_assign_test_all_8_combinations() {
1288 fn matrix() -> Matrix<i8> {
1289 Matrix::from_scalar(1)
1290 }
1291 fn matrix_view() -> MatrixView<i8, Matrix<i8>> {
1292 MatrixView::from(Matrix::from_scalar(1))
1293 }
1294 let mut results_matrix = Vec::with_capacity(16);
1295 let mut results_matrix_views = Vec::with_capacity(16);
1296 results_matrix.push({
1297 let mut x = matrix();
1298 x -= matrix();
1299 x
1300 });
1301 results_matrix.push({
1302 let mut x = matrix();
1303 x -= &matrix();
1304 x
1305 });
1306 results_matrix_views.push({
1307 let mut x = matrix_view();
1308 x -= matrix();
1309 x
1310 });
1311 results_matrix_views.push({
1312 let mut x = matrix_view();
1313 x -= &matrix();
1314 x
1315 });
1316 results_matrix.push({
1317 let mut x = matrix();
1318 x -= matrix_view();
1319 x
1320 });
1321 results_matrix.push({
1322 let mut x = matrix();
1323 x -= &matrix_view();
1324 x
1325 });
1326 results_matrix_views.push({
1327 let mut x = matrix_view();
1328 x -= matrix_view();
1329 x
1330 });
1331 results_matrix_views.push({
1332 let mut x = matrix_view();
1333 x -= &matrix_view();
1334 x
1335 });
1336 for total in results_matrix {
1337 assert_eq!(total.scalar(), 0);
1338 }
1339 for total in results_matrix_views {
1340 assert_eq!(total.get(0, 0), 0);
1341 }
1342}
1343
1344impl<T: Numeric> Neg for &Matrix<T>
1348where
1349 for<'a> &'a T: NumericRef<T>,
1350{
1351 type Output = Matrix<T>;
1352
1353 #[inline]
1354 fn neg(self) -> Self::Output {
1355 self.map(|v| -v)
1356 }
1357}
1358
1359impl<T: Numeric> Neg for Matrix<T>
1363where
1364 for<'a> &'a T: NumericRef<T>,
1365{
1366 type Output = Matrix<T>;
1367
1368 #[inline]
1369 fn neg(self) -> Self::Output {
1370 -&self
1371 }
1372}
1373
1374impl<T, S> Neg for &MatrixView<T, S>
1378where
1379 T: Numeric,
1380 for<'a> &'a T: NumericRef<T>,
1381 S: MatrixRef<T>,
1382{
1383 type Output = Matrix<T>;
1384
1385 #[inline]
1386 fn neg(self) -> Self::Output {
1387 self.map(|v| -v)
1388 }
1389}
1390
1391impl<T, S> Neg for MatrixView<T, S>
1395where
1396 T: Numeric,
1397 for<'a> &'a T: NumericRef<T>,
1398 S: MatrixRef<T>,
1399{
1400 type Output = Matrix<T>;
1401
1402 #[inline]
1403 fn neg(self) -> Self::Output {
1404 -&self
1405 }
1406}
1407
1408macro_rules! matrix_scalar {
1409 (impl $op:tt for Matrix { fn $method:ident }) => {
1410 impl<T: Numeric> $op<&T> for &Matrix<T>
1415 where
1416 for<'a> &'a T: NumericRef<T>,
1417 {
1418 type Output = Matrix<T>;
1419 #[inline]
1420 fn $method(self, rhs: &T) -> Self::Output {
1421 self.map(|x| (x).$method(rhs.clone()))
1422 }
1423 }
1424
1425 impl<T: Numeric> $op<&T> for Matrix<T>
1430 where
1431 for<'a> &'a T: NumericRef<T>,
1432 {
1433 type Output = Matrix<T>;
1434 #[inline]
1435 fn $method(self, rhs: &T) -> Self::Output {
1436 self.map(|x| (x).$method(rhs.clone()))
1437 }
1438 }
1439
1440 impl<T: Numeric> $op<T> for &Matrix<T>
1445 where
1446 for<'a> &'a T: NumericRef<T>,
1447 {
1448 type Output = Matrix<T>;
1449 #[inline]
1450 fn $method(self, rhs: T) -> Self::Output {
1451 self.map(|x| (x).$method(rhs.clone()))
1452 }
1453 }
1454
1455 impl<T: Numeric> $op<T> for Matrix<T>
1460 where
1461 for<'a> &'a T: NumericRef<T>,
1462 {
1463 type Output = Matrix<T>;
1464 #[inline]
1465 fn $method(self, rhs: T) -> Self::Output {
1466 self.map(|x| (x).$method(rhs.clone()))
1467 }
1468 }
1469 };
1470}
1471
1472macro_rules! matrix_view_scalar {
1473 (impl $op:tt for MatrixView { fn $method:ident }) => {
1474 impl<T, S> $op<&T> for &MatrixView<T, S>
1479 where
1480 T: Numeric,
1481 for<'a> &'a T: NumericRef<T>,
1482 S: MatrixRef<T>,
1483 {
1484 type Output = Matrix<T>;
1485 #[inline]
1486 fn $method(self, rhs: &T) -> Self::Output {
1487 self.map(|x| (x).$method(rhs.clone()))
1488 }
1489 }
1490
1491 impl<T, S> $op<&T> for MatrixView<T, S>
1496 where
1497 T: Numeric,
1498 for<'a> &'a T: NumericRef<T>,
1499 S: MatrixRef<T>,
1500 {
1501 type Output = Matrix<T>;
1502 #[inline]
1503 fn $method(self, rhs: &T) -> Self::Output {
1504 self.map(|x| (x).$method(rhs.clone()))
1505 }
1506 }
1507
1508 impl<T, S> $op<T> for &MatrixView<T, S>
1513 where
1514 T: Numeric,
1515 for<'a> &'a T: NumericRef<T>,
1516 S: MatrixRef<T>,
1517 {
1518 type Output = Matrix<T>;
1519 #[inline]
1520 fn $method(self, rhs: T) -> Self::Output {
1521 self.map(|x| (x).$method(rhs.clone()))
1522 }
1523 }
1524
1525 impl<T, S> $op<T> for MatrixView<T, S>
1530 where
1531 T: Numeric,
1532 for<'a> &'a T: NumericRef<T>,
1533 S: MatrixRef<T>,
1534 {
1535 type Output = Matrix<T>;
1536 #[inline]
1537 fn $method(self, rhs: T) -> Self::Output {
1538 self.map(|x| (x).$method(rhs.clone()))
1539 }
1540 }
1541 };
1542}
1543
1544matrix_scalar!(impl Add for Matrix { fn add });
1545matrix_scalar!(impl Sub for Matrix { fn sub });
1546matrix_scalar!(impl Mul for Matrix { fn mul });
1547matrix_scalar!(impl Div for Matrix { fn div });
1548
1549matrix_view_scalar!(impl Add for MatrixView { fn add });
1550matrix_view_scalar!(impl Sub for MatrixView { fn sub });
1551matrix_view_scalar!(impl Mul for MatrixView { fn mul });
1552matrix_view_scalar!(impl Div for MatrixView { fn div });