1use super::*;
4use crate::{
5 assert,
6 permutation::{Index, SignedIndex},
7 sparse,
8};
9
10pub struct Scalar {
12 __private: (),
13}
14pub struct DenseCol {
16 __private: (),
17}
18pub struct DenseRow {
20 __private: (),
21}
22pub struct Dense {
24 __private: (),
25}
26pub struct SparseColMat<I: Index> {
28 __private: PhantomData<I>,
29}
30pub struct SparseRowMat<I: Index> {
32 __private: PhantomData<I>,
33}
34pub struct Diag {
36 __private: (),
37}
38pub struct Scale {
40 __private: (),
41}
42pub struct Perm<I> {
44 __private: PhantomData<I>,
45}
46
47pub trait MatrixKind {
49 type Ref<'a, E: Entity>: Copy;
51 type Mut<'a, E: Entity>;
53 type Own<E: Entity>;
55}
56type KindRef<'a, E, K> = <K as MatrixKind>::Ref<'a, E>;
57type KindMut<'a, E, K> = <K as MatrixKind>::Mut<'a, E>;
58type KindOwn<E, K> = <K as MatrixKind>::Own<E>;
59
60impl MatrixKind for Scalar {
61 type Ref<'a, E: Entity> = &'a E;
62 type Mut<'a, E: Entity> = &'a mut E;
63 type Own<E: Entity> = E;
64}
65impl MatrixKind for DenseCol {
66 type Ref<'a, E: Entity> = ColRef<'a, E>;
67 type Mut<'a, E: Entity> = ColMut<'a, E>;
68 type Own<E: Entity> = Col<E>;
69}
70impl MatrixKind for DenseRow {
71 type Ref<'a, E: Entity> = RowRef<'a, E>;
72 type Mut<'a, E: Entity> = RowMut<'a, E>;
73 type Own<E: Entity> = Row<E>;
74}
75impl MatrixKind for Dense {
76 type Ref<'a, E: Entity> = MatRef<'a, E>;
77 type Mut<'a, E: Entity> = MatMut<'a, E>;
78 type Own<E: Entity> = Mat<E>;
79}
80impl<I: Index> MatrixKind for SparseColMat<I> {
81 type Ref<'a, E: Entity> = sparse::SparseColMatRef<'a, I, E>;
82 type Mut<'a, E: Entity> = sparse::SparseColMatMut<'a, I, E>;
83 type Own<E: Entity> = sparse::SparseColMat<I, E>;
84}
85impl<I: Index> MatrixKind for SparseRowMat<I> {
86 type Ref<'a, E: Entity> = sparse::SparseRowMatRef<'a, I, E>;
87 type Mut<'a, E: Entity> = sparse::SparseRowMatMut<'a, I, E>;
88 type Own<E: Entity> = sparse::SparseRowMat<I, E>;
89}
90impl MatrixKind for Scale {
91 type Ref<'a, E: Entity> = &'a MatScale<E>;
92 type Mut<'a, E: Entity> = &'a mut MatScale<E>;
93 type Own<E: Entity> = MatScale<E>;
94}
95impl MatrixKind for Diag {
96 type Ref<'a, E: Entity> = Matrix<inner::DiagRef<'a, E>>;
97 type Mut<'a, E: Entity> = Matrix<inner::DiagMut<'a, E>>;
98 type Own<E: Entity> = Matrix<inner::DiagOwn<E>>;
99}
100impl<I: Index> MatrixKind for Perm<I> {
101 type Ref<'a, E: Entity> = Matrix<inner::PermRef<'a, I, E>>;
102 type Mut<'a, E: Entity> = Matrix<inner::PermMut<'a, I, E>>;
103 type Own<E: Entity> = Matrix<inner::PermOwn<I, E>>;
104}
105
106pub trait GenericMatrix: Sized {
108 type Kind: MatrixKind;
110 type Elem: Entity;
112
113 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem>;
115}
116pub trait GenericMatrixMut: GenericMatrix {
118 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem>;
120}
121
122impl<I: Index, E: Entity> GenericMatrix for inner::PermRef<'_, I, E> {
123 type Kind = Perm<I>;
124 type Elem = E;
125
126 #[inline(always)]
127 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
128 *this
129 }
130}
131impl<I: Index, E: Entity> GenericMatrix for inner::PermMut<'_, I, E> {
132 type Kind = Perm<I>;
133 type Elem = E;
134
135 #[inline(always)]
136 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
137 this.rb()
138 }
139}
140impl<I: Index, E: Entity> GenericMatrix for inner::PermOwn<I, E> {
141 type Kind = Perm<I>;
142 type Elem = E;
143
144 #[inline(always)]
145 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
146 this.as_ref()
147 }
148}
149
150impl<E: Entity> GenericMatrix for inner::DenseRowRef<'_, E> {
151 type Kind = DenseRow;
152 type Elem = E;
153
154 #[inline(always)]
155 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
156 *this
157 }
158}
159impl<E: Entity> GenericMatrix for inner::DenseRowMut<'_, E> {
160 type Kind = DenseRow;
161 type Elem = E;
162
163 #[inline(always)]
164 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
165 this.rb()
166 }
167}
168impl<E: Entity> GenericMatrix for inner::DenseRowOwn<E> {
169 type Kind = DenseRow;
170 type Elem = E;
171
172 #[inline(always)]
173 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
174 this.as_ref()
175 }
176}
177impl<E: Entity> GenericMatrixMut for inner::DenseRowMut<'_, E> {
178 #[inline(always)]
179 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
180 this.rb_mut()
181 }
182}
183impl<E: Entity> GenericMatrixMut for inner::DenseRowOwn<E> {
184 #[inline(always)]
185 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
186 this.as_mut()
187 }
188}
189
190impl<E: Entity> GenericMatrix for inner::DenseColRef<'_, E> {
191 type Kind = DenseCol;
192 type Elem = E;
193
194 #[inline(always)]
195 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
196 *this
197 }
198}
199impl<E: Entity> GenericMatrix for inner::DenseColMut<'_, E> {
200 type Kind = DenseCol;
201 type Elem = E;
202
203 #[inline(always)]
204 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
205 this.rb()
206 }
207}
208impl<E: Entity> GenericMatrix for inner::DenseColOwn<E> {
209 type Kind = DenseCol;
210 type Elem = E;
211
212 #[inline(always)]
213 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
214 this.as_ref()
215 }
216}
217impl<E: Entity> GenericMatrixMut for inner::DenseColMut<'_, E> {
218 #[inline(always)]
219 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
220 this.rb_mut()
221 }
222}
223impl<E: Entity> GenericMatrixMut for inner::DenseColOwn<E> {
224 #[inline(always)]
225 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
226 this.as_mut()
227 }
228}
229
230impl<E: Entity> GenericMatrix for inner::DenseRef<'_, E> {
231 type Kind = Dense;
232 type Elem = E;
233
234 #[inline(always)]
235 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
236 *this
237 }
238}
239impl<E: Entity> GenericMatrix for inner::DenseMut<'_, E> {
240 type Kind = Dense;
241 type Elem = E;
242
243 #[inline(always)]
244 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
245 this.rb()
246 }
247}
248impl<E: Entity> GenericMatrix for inner::DenseOwn<E> {
249 type Kind = Dense;
250 type Elem = E;
251
252 #[inline(always)]
253 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
254 this.as_ref()
255 }
256}
257impl<E: Entity> GenericMatrixMut for inner::DenseMut<'_, E> {
258 #[inline(always)]
259 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
260 this.rb_mut()
261 }
262}
263impl<E: Entity> GenericMatrixMut for inner::DenseOwn<E> {
264 #[inline(always)]
265 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
266 this.as_mut()
267 }
268}
269
270impl<E: Entity> GenericMatrix for inner::DiagRef<'_, E> {
271 type Kind = Diag;
272 type Elem = E;
273
274 #[inline(always)]
275 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
276 *this
277 }
278}
279impl<E: Entity> GenericMatrix for inner::DiagMut<'_, E> {
280 type Kind = Diag;
281 type Elem = E;
282
283 #[inline(always)]
284 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
285 this.rb()
286 }
287}
288impl<E: Entity> GenericMatrix for inner::DiagOwn<E> {
289 type Kind = Diag;
290 type Elem = E;
291
292 #[inline(always)]
293 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
294 this.as_ref()
295 }
296}
297impl<E: Entity> GenericMatrixMut for inner::DiagMut<'_, E> {
298 #[inline(always)]
299 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
300 this.rb_mut()
301 }
302}
303impl<E: Entity> GenericMatrixMut for inner::DiagOwn<E> {
304 #[inline(always)]
305 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
306 this.as_mut()
307 }
308}
309
310impl<E: Entity> GenericMatrix for inner::Scale<E> {
311 type Kind = Scale;
312 type Elem = E;
313
314 #[inline(always)]
315 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
316 this
317 }
318}
319impl<E: Entity> GenericMatrixMut for inner::Scale<E> {
320 #[inline(always)]
321 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
322 this
323 }
324}
325
326impl<I: Index, E: Entity> GenericMatrix for inner::SparseColMatRef<'_, I, E> {
327 type Kind = SparseColMat<I>;
328 type Elem = E;
329
330 #[inline(always)]
331 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
332 *this
333 }
334}
335
336impl<I: Index, E: Entity> GenericMatrix for inner::SparseRowMatRef<'_, I, E> {
337 type Kind = SparseRowMat<I>;
338 type Elem = E;
339
340 #[inline(always)]
341 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
342 *this
343 }
344}
345
346impl<I: Index, E: Entity> GenericMatrix for inner::SparseColMatMut<'_, I, E> {
347 type Kind = SparseColMat<I>;
348 type Elem = E;
349
350 #[inline(always)]
351 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
352 this.rb()
353 }
354}
355
356impl<I: Index, E: Entity> GenericMatrix for inner::SparseRowMatMut<'_, I, E> {
357 type Kind = SparseRowMat<I>;
358 type Elem = E;
359
360 #[inline(always)]
361 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
362 this.rb()
363 }
364}
365
366impl<I: Index, E: Entity> GenericMatrixMut for inner::SparseColMatMut<'_, I, E> {
367 #[inline(always)]
368 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
369 this.rb_mut()
370 }
371}
372
373impl<I: Index, E: Entity> GenericMatrixMut for inner::SparseRowMatMut<'_, I, E> {
374 #[inline(always)]
375 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
376 this.rb_mut()
377 }
378}
379
380impl<I: Index, E: Entity> GenericMatrix for inner::SparseColMat<I, E> {
381 type Kind = SparseColMat<I>;
382 type Elem = E;
383
384 #[inline(always)]
385 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
386 this.as_ref()
387 }
388}
389
390impl<I: Index, E: Entity> GenericMatrix for inner::SparseRowMat<I, E> {
391 type Kind = SparseRowMat<I>;
392 type Elem = E;
393
394 #[inline(always)]
395 fn as_ref(this: &Matrix<Self>) -> <Self::Kind as MatrixKind>::Ref<'_, Self::Elem> {
396 this.as_ref()
397 }
398}
399
400impl<I: Index, E: Entity> GenericMatrixMut for inner::SparseColMat<I, E> {
401 #[inline(always)]
402 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
403 this.as_mut()
404 }
405}
406
407impl<I: Index, E: Entity> GenericMatrixMut for inner::SparseRowMat<I, E> {
408 #[inline(always)]
409 fn as_mut(this: &mut Matrix<Self>) -> <Self::Kind as MatrixKind>::Mut<'_, Self::Elem> {
410 this.as_mut()
411 }
412}
413
414mod __matmul_assign {
415 use super::*;
416
417 impl MatMulAssign<Scale> for DenseCol {
418 #[track_caller]
419 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
420 lhs: KindMut<'_, E, DenseCol>,
421 rhs: KindRef<'_, RhsE, Scale>,
422 ) {
423 let rhs = rhs.value().canonicalize();
424 zipped!(lhs.as_2d_mut())
425 .for_each(|unzipped!(mut lhs)| lhs.write(lhs.read().faer_mul(rhs)));
426 }
427 }
428 impl MatMulAssign<Scale> for DenseRow {
429 #[track_caller]
430 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
431 lhs: KindMut<'_, E, DenseRow>,
432 rhs: KindRef<'_, RhsE, Scale>,
433 ) {
434 let rhs = rhs.value().canonicalize();
435 zipped!(lhs.as_2d_mut())
436 .for_each(|unzipped!(mut lhs)| lhs.write(lhs.read().faer_mul(rhs)));
437 }
438 }
439 impl MatMulAssign<Scale> for Dense {
440 #[track_caller]
441 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
442 lhs: KindMut<'_, E, Dense>,
443 rhs: KindRef<'_, RhsE, Scale>,
444 ) {
445 let rhs = rhs.value().canonicalize();
446 zipped!(lhs).for_each(|unzipped!(mut lhs)| lhs.write(lhs.read().faer_mul(rhs)));
447 }
448 }
449 impl MatMulAssign<Scale> for Scale {
450 #[track_caller]
451 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
452 lhs: KindMut<'_, E, Scale>,
453 rhs: KindRef<'_, RhsE, Scale>,
454 ) {
455 let rhs = rhs.value().canonicalize();
456 *lhs = scale((*lhs).value().faer_mul(rhs));
457 }
458 }
459
460 impl MatMulAssign<Diag> for Diag {
461 #[track_caller]
462 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
463 lhs: KindMut<'_, E, Diag>,
464 rhs: KindRef<'_, RhsE, Diag>,
465 ) {
466 zipped!(lhs.inner.inner.as_2d_mut(), rhs.inner.inner.as_2d()).for_each(
467 |unzipped!(mut lhs, rhs)| lhs.write(lhs.read().faer_mul(rhs.read().canonicalize())),
468 );
469 }
470 }
471}
472
473mod __matmul {
474 use super::*;
475 use crate::{assert, permutation::Permutation};
476
477 impl<I: Index> MatMul<Perm<I>> for Perm<I> {
478 type Output = Perm<I>;
479
480 #[track_caller]
481 fn mat_mul<
482 E: ComplexField,
483 LhsE: Conjugate<Canonical = E>,
484 RhsE: Conjugate<Canonical = E>,
485 >(
486 lhs: KindRef<'_, LhsE, Perm<I>>,
487 rhs: KindRef<'_, RhsE, Perm<I>>,
488 ) -> KindOwn<E, Self::Output> {
489 assert!(lhs.len() == rhs.len());
490 let truncate = <I::Signed as SignedIndex>::truncate;
491 let mut fwd = alloc::vec![I::from_signed(truncate(0)); lhs.len()].into_boxed_slice();
492 let mut inv = alloc::vec![I::from_signed(truncate(0)); lhs.len()].into_boxed_slice();
493
494 for (fwd, rhs) in fwd.iter_mut().zip(rhs.inner.forward) {
495 *fwd = lhs.inner.forward[rhs.to_signed().zx()];
496 }
497 for (i, fwd) in fwd.iter().enumerate() {
498 inv[fwd.to_signed().zx()] = I::from_signed(I::Signed::truncate(i));
499 }
500
501 Permutation {
502 inner: inner::PermOwn {
503 forward: fwd,
504 inverse: inv,
505 __marker: core::marker::PhantomData,
506 },
507 }
508 }
509 }
510
511 impl<I: Index> MatMul<DenseCol> for Perm<I> {
512 type Output = DenseCol;
513
514 #[track_caller]
515 fn mat_mul<
516 E: ComplexField,
517 LhsE: Conjugate<Canonical = E>,
518 RhsE: Conjugate<Canonical = E>,
519 >(
520 lhs: KindRef<'_, LhsE, Perm<I>>,
521 rhs: KindRef<'_, RhsE, DenseCol>,
522 ) -> KindOwn<E, Self::Output> {
523 assert!(lhs.len() == rhs.nrows());
524 let mut out = Col::zeros(rhs.nrows());
525 let fwd = lhs.inner.forward;
526 for (i, fwd) in fwd.iter().enumerate() {
527 out.write(i, rhs.read(fwd.to_signed().zx()).canonicalize());
528 }
529 out
530 }
531 }
532 impl<I: Index> MatMul<Dense> for Perm<I> {
533 type Output = Dense;
534
535 #[track_caller]
536 fn mat_mul<
537 E: ComplexField,
538 LhsE: Conjugate<Canonical = E>,
539 RhsE: Conjugate<Canonical = E>,
540 >(
541 lhs: KindRef<'_, LhsE, Perm<I>>,
542 rhs: KindRef<'_, RhsE, Dense>,
543 ) -> KindOwn<E, Self::Output> {
544 assert!(lhs.len() == rhs.nrows());
545 let mut out = Mat::zeros(rhs.nrows(), rhs.ncols());
546 let fwd = lhs.inner.forward;
547
548 for j in 0..rhs.ncols() {
549 for (i, fwd) in fwd.iter().enumerate() {
550 out.write(i, j, rhs.read(fwd.to_signed().zx(), j).canonicalize());
551 }
552 }
553 out
554 }
555 }
556 impl<I: Index> MatMul<Perm<I>> for DenseRow {
557 type Output = DenseRow;
558
559 #[track_caller]
560 fn mat_mul<
561 E: ComplexField,
562 LhsE: Conjugate<Canonical = E>,
563 RhsE: Conjugate<Canonical = E>,
564 >(
565 lhs: KindRef<'_, LhsE, DenseRow>,
566 rhs: KindRef<'_, RhsE, Perm<I>>,
567 ) -> KindOwn<E, Self::Output> {
568 assert!(lhs.ncols() == rhs.len());
569 let mut out = Row::zeros(lhs.ncols());
570 let inv = rhs.inner.inverse;
571
572 for (j, inv) in inv.iter().enumerate() {
573 out.write(j, lhs.read(inv.to_signed().zx()).canonicalize());
574 }
575 out
576 }
577 }
578 impl<I: Index> MatMul<Perm<I>> for Dense {
579 type Output = Dense;
580
581 #[track_caller]
582 fn mat_mul<
583 E: ComplexField,
584 LhsE: Conjugate<Canonical = E>,
585 RhsE: Conjugate<Canonical = E>,
586 >(
587 lhs: KindRef<'_, LhsE, Dense>,
588 rhs: KindRef<'_, RhsE, Perm<I>>,
589 ) -> KindOwn<E, Self::Output> {
590 assert!(lhs.ncols() == rhs.len());
591 let mut out = Mat::zeros(lhs.nrows(), lhs.ncols());
592 let inv = rhs.inner.inverse;
593
594 for (j, inv) in inv.iter().enumerate() {
595 for i in 0..lhs.nrows() {
596 out.write(i, j, lhs.read(i, inv.to_signed().zx()).canonicalize());
597 }
598 }
599 out
600 }
601 }
602
603 impl MatMul<DenseCol> for Scale {
604 type Output = DenseCol;
605
606 #[track_caller]
607 fn mat_mul<
608 E: ComplexField,
609 LhsE: Conjugate<Canonical = E>,
610 RhsE: Conjugate<Canonical = E>,
611 >(
612 lhs: KindRef<'_, LhsE, Scale>,
613 rhs: KindRef<'_, RhsE, DenseCol>,
614 ) -> KindOwn<E, Self::Output> {
615 let mut out = Col::<E>::zeros(rhs.nrows());
616 let lhs = lhs.inner.0.canonicalize();
617 zipped!(out.as_mut().as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut out, rhs)| {
618 out.write(E::faer_mul(lhs, rhs.read().canonicalize()))
619 });
620 out
621 }
622 }
623 impl MatMul<Scale> for DenseCol {
624 type Output = DenseCol;
625
626 #[track_caller]
627 fn mat_mul<
628 E: ComplexField,
629 LhsE: Conjugate<Canonical = E>,
630 RhsE: Conjugate<Canonical = E>,
631 >(
632 lhs: KindRef<'_, LhsE, DenseCol>,
633 rhs: KindRef<'_, RhsE, Scale>,
634 ) -> KindOwn<E, Self::Output> {
635 let mut out = Col::<E>::zeros(lhs.nrows());
636 let rhs = rhs.inner.0.canonicalize();
637 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d()).for_each(|unzipped!(mut out, lhs)| {
638 out.write(E::faer_mul(lhs.read().canonicalize(), rhs))
639 });
640 out
641 }
642 }
643 impl MatMul<DenseRow> for Scale {
644 type Output = DenseRow;
645
646 #[track_caller]
647 fn mat_mul<
648 E: ComplexField,
649 LhsE: Conjugate<Canonical = E>,
650 RhsE: Conjugate<Canonical = E>,
651 >(
652 lhs: KindRef<'_, LhsE, Scale>,
653 rhs: KindRef<'_, RhsE, DenseRow>,
654 ) -> KindOwn<E, Self::Output> {
655 let mut out = Row::<E>::zeros(rhs.nrows());
656 let lhs = lhs.inner.0.canonicalize();
657 zipped!(out.as_mut().as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut out, rhs)| {
658 out.write(E::faer_mul(lhs, rhs.read().canonicalize()))
659 });
660 out
661 }
662 }
663 impl MatMul<Scale> for DenseRow {
664 type Output = DenseRow;
665
666 #[track_caller]
667 fn mat_mul<
668 E: ComplexField,
669 LhsE: Conjugate<Canonical = E>,
670 RhsE: Conjugate<Canonical = E>,
671 >(
672 lhs: KindRef<'_, LhsE, DenseRow>,
673 rhs: KindRef<'_, RhsE, Scale>,
674 ) -> KindOwn<E, Self::Output> {
675 let mut out = Row::<E>::zeros(lhs.nrows());
676 let rhs = rhs.inner.0.canonicalize();
677 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d()).for_each(|unzipped!(mut out, lhs)| {
678 out.write(E::faer_mul(lhs.read().canonicalize(), rhs))
679 });
680 out
681 }
682 }
683 impl MatMul<Dense> for Scale {
684 type Output = Dense;
685
686 #[track_caller]
687 fn mat_mul<
688 E: ComplexField,
689 LhsE: Conjugate<Canonical = E>,
690 RhsE: Conjugate<Canonical = E>,
691 >(
692 lhs: KindRef<'_, LhsE, Scale>,
693 rhs: KindRef<'_, RhsE, Dense>,
694 ) -> KindOwn<E, Self::Output> {
695 let mut out = Mat::<E>::zeros(rhs.nrows(), rhs.ncols());
696 let lhs = lhs.inner.0.canonicalize();
697 zipped!(out.as_mut(), rhs).for_each(|unzipped!(mut out, rhs)| {
698 out.write(E::faer_mul(lhs, rhs.read().canonicalize()))
699 });
700 out
701 }
702 }
703 impl MatMul<Scale> for Dense {
704 type Output = Dense;
705
706 #[track_caller]
707 fn mat_mul<
708 E: ComplexField,
709 LhsE: Conjugate<Canonical = E>,
710 RhsE: Conjugate<Canonical = E>,
711 >(
712 lhs: KindRef<'_, LhsE, Dense>,
713 rhs: KindRef<'_, RhsE, Scale>,
714 ) -> KindOwn<E, Self::Output> {
715 let mut out = Mat::<E>::zeros(lhs.nrows(), lhs.ncols());
716 let rhs = rhs.inner.0.canonicalize();
717 zipped!(out.as_mut(), lhs).for_each(|unzipped!(mut out, lhs)| {
718 out.write(E::faer_mul(lhs.read().canonicalize(), rhs))
719 });
720 out
721 }
722 }
723 impl MatMul<Scale> for Scale {
724 type Output = Scale;
725
726 #[track_caller]
727 fn mat_mul<
728 E: ComplexField,
729 LhsE: Conjugate<Canonical = E>,
730 RhsE: Conjugate<Canonical = E>,
731 >(
732 lhs: KindRef<'_, LhsE, Scale>,
733 rhs: KindRef<'_, RhsE, Scale>,
734 ) -> KindOwn<E, Self::Output> {
735 scale(E::faer_mul(
736 lhs.inner.0.canonicalize(),
737 rhs.inner.0.canonicalize(),
738 ))
739 }
740 }
741
742 impl MatMul<Diag> for DenseRow {
743 type Output = DenseRow;
744
745 #[track_caller]
746 fn mat_mul<
747 E: ComplexField,
748 LhsE: Conjugate<Canonical = E>,
749 RhsE: Conjugate<Canonical = E>,
750 >(
751 lhs: KindRef<'_, LhsE, DenseRow>,
752 rhs: KindRef<'_, RhsE, Diag>,
753 ) -> KindOwn<E, Self::Output> {
754 let lhs_ncols = lhs.ncols();
755 let rhs_dim = rhs.inner.inner.nrows();
756 assert!(lhs_ncols == rhs_dim);
757
758 Row::from_fn(lhs_ncols, |j| unsafe {
759 E::faer_mul(
760 lhs.read_unchecked(j).canonicalize(),
761 rhs.inner.inner.read_unchecked(j).canonicalize(),
762 )
763 })
764 }
765 }
766 impl MatMul<Diag> for Dense {
767 type Output = Dense;
768
769 #[track_caller]
770 fn mat_mul<
771 E: ComplexField,
772 LhsE: Conjugate<Canonical = E>,
773 RhsE: Conjugate<Canonical = E>,
774 >(
775 lhs: KindRef<'_, LhsE, Dense>,
776 rhs: KindRef<'_, RhsE, Diag>,
777 ) -> KindOwn<E, Self::Output> {
778 let lhs_ncols = lhs.ncols();
779 let rhs_dim = rhs.inner.inner.nrows();
780 assert!(lhs_ncols == rhs_dim);
781
782 Mat::from_fn(lhs.nrows(), lhs.ncols(), |i, j| unsafe {
783 E::faer_mul(
784 lhs.read_unchecked(i, j).canonicalize(),
785 rhs.inner.inner.read_unchecked(j).canonicalize(),
786 )
787 })
788 }
789 }
790
791 impl MatMul<DenseCol> for Diag {
792 type Output = DenseCol;
793
794 #[track_caller]
795 fn mat_mul<
796 E: ComplexField,
797 LhsE: Conjugate<Canonical = E>,
798 RhsE: Conjugate<Canonical = E>,
799 >(
800 lhs: KindRef<'_, LhsE, Diag>,
801 rhs: KindRef<'_, RhsE, DenseCol>,
802 ) -> KindOwn<E, Self::Output> {
803 let lhs_dim = lhs.inner.inner.nrows();
804 let rhs_nrows = rhs.nrows();
805 assert!(lhs_dim == rhs_nrows);
806
807 Col::from_fn(rhs.nrows(), |i| unsafe {
808 E::faer_mul(
809 lhs.inner.inner.read_unchecked(i).canonicalize(),
810 rhs.read_unchecked(i).canonicalize(),
811 )
812 })
813 }
814 }
815 impl MatMul<Dense> for Diag {
816 type Output = Dense;
817
818 #[track_caller]
819 fn mat_mul<
820 E: ComplexField,
821 LhsE: Conjugate<Canonical = E>,
822 RhsE: Conjugate<Canonical = E>,
823 >(
824 lhs: KindRef<'_, LhsE, Diag>,
825 rhs: KindRef<'_, RhsE, Dense>,
826 ) -> KindOwn<E, Self::Output> {
827 let lhs_dim = lhs.inner.inner.nrows();
828 let rhs_nrows = rhs.nrows();
829 assert!(lhs_dim == rhs_nrows);
830
831 Mat::from_fn(rhs.nrows(), rhs.ncols(), |i, j| unsafe {
832 E::faer_mul(
833 lhs.inner.inner.read_unchecked(i).canonicalize(),
834 rhs.read_unchecked(i, j).canonicalize(),
835 )
836 })
837 }
838 }
839
840 impl MatMul<Diag> for Diag {
841 type Output = Diag;
842
843 #[track_caller]
844 fn mat_mul<
845 E: ComplexField,
846 LhsE: Conjugate<Canonical = E>,
847 RhsE: Conjugate<Canonical = E>,
848 >(
849 lhs: KindRef<'_, LhsE, Diag>,
850 rhs: KindRef<'_, RhsE, Diag>,
851 ) -> KindOwn<E, Self::Output> {
852 let lhs_dim = lhs.inner.inner.nrows();
853 let rhs_dim = rhs.inner.inner.nrows();
854 assert!(lhs_dim == rhs_dim);
855
856 Matrix {
857 inner: inner::DiagOwn {
858 inner: Col::from_fn(lhs_dim, |i| unsafe {
859 E::faer_mul(
860 lhs.inner.inner.read_unchecked(i).canonicalize(),
861 rhs.inner.inner.read_unchecked(i).canonicalize(),
862 )
863 }),
864 },
865 }
866 }
867 }
868
869 impl MatMul<Dense> for Dense {
870 type Output = Dense;
871
872 #[track_caller]
873 fn mat_mul<
874 E: ComplexField,
875 LhsE: Conjugate<Canonical = E>,
876 RhsE: Conjugate<Canonical = E>,
877 >(
878 lhs: KindRef<'_, LhsE, Self>,
879 rhs: KindRef<'_, RhsE, Self>,
880 ) -> KindOwn<E, Self::Output> {
881 assert!(lhs.ncols() == rhs.nrows());
882 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
883 mul::matmul(
884 out.as_mut(),
885 lhs,
886 rhs,
887 None,
888 E::faer_one(),
889 get_global_parallelism(),
890 );
891 out
892 }
893 }
894
895 impl MatMul<DenseCol> for Dense {
896 type Output = DenseCol;
897
898 #[track_caller]
899 fn mat_mul<
900 E: ComplexField,
901 LhsE: Conjugate<Canonical = E>,
902 RhsE: Conjugate<Canonical = E>,
903 >(
904 lhs: KindRef<'_, LhsE, Dense>,
905 rhs: KindRef<'_, RhsE, DenseCol>,
906 ) -> KindOwn<E, Self::Output> {
907 assert!(lhs.ncols() == rhs.nrows());
908 let mut out = Col::zeros(lhs.nrows());
909 mul::matmul(
910 out.as_mut().as_2d_mut(),
911 lhs,
912 rhs.as_2d(),
913 None,
914 E::faer_one(),
915 get_global_parallelism(),
916 );
917 out
918 }
919 }
920 impl MatMul<Dense> for DenseRow {
921 type Output = DenseRow;
922
923 #[track_caller]
924 fn mat_mul<
925 E: ComplexField,
926 LhsE: Conjugate<Canonical = E>,
927 RhsE: Conjugate<Canonical = E>,
928 >(
929 lhs: KindRef<'_, LhsE, DenseRow>,
930 rhs: KindRef<'_, RhsE, Dense>,
931 ) -> KindOwn<E, Self::Output> {
932 assert!(lhs.ncols() == rhs.nrows());
933 let mut out = Row::zeros(lhs.nrows());
934 mul::matmul(
935 out.as_mut().as_2d_mut(),
936 lhs.as_2d(),
937 rhs,
938 None,
939 E::faer_one(),
940 get_global_parallelism(),
941 );
942 out
943 }
944 }
945
946 impl MatMul<DenseCol> for DenseRow {
947 type Output = Scalar;
948
949 #[track_caller]
950 fn mat_mul<
951 E: ComplexField,
952 LhsE: Conjugate<Canonical = E>,
953 RhsE: Conjugate<Canonical = E>,
954 >(
955 lhs: KindRef<'_, LhsE, DenseRow>,
956 rhs: KindRef<'_, RhsE, DenseCol>,
957 ) -> KindOwn<E, Self::Output> {
958 assert!(lhs.ncols() == rhs.nrows());
959 let (lhs, conj_lhs) = lhs.canonicalize();
960 let (rhs, conj_rhs) = rhs.canonicalize();
961
962 crate::mul::inner_prod::inner_prod_with_conj(
963 lhs.transpose().as_2d(),
964 conj_lhs,
965 rhs.as_2d(),
966 conj_rhs,
967 )
968 }
969 }
970
971 impl MatMul<DenseRow> for DenseCol {
972 type Output = Dense;
973
974 #[track_caller]
975 fn mat_mul<
976 E: ComplexField,
977 LhsE: Conjugate<Canonical = E>,
978 RhsE: Conjugate<Canonical = E>,
979 >(
980 lhs: KindRef<'_, LhsE, DenseCol>,
981 rhs: KindRef<'_, RhsE, DenseRow>,
982 ) -> KindOwn<E, Self::Output> {
983 assert!(lhs.ncols() == rhs.nrows());
984 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
985 mul::matmul(
986 out.as_mut(),
987 lhs.as_2d(),
988 rhs.as_2d(),
989 None,
990 E::faer_one(),
991 get_global_parallelism(),
992 );
993 out
994 }
995 }
996
997 impl<I: Index> MatMul<SparseColMat<I>> for Dense {
998 type Output = Dense;
999
1000 #[track_caller]
1001 fn mat_mul<
1002 E: ComplexField,
1003 LhsE: Conjugate<Canonical = E>,
1004 RhsE: Conjugate<Canonical = E>,
1005 >(
1006 lhs: KindRef<'_, LhsE, Self>,
1007 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1008 ) -> KindOwn<E, Self::Output> {
1009 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
1010 sparse::mul::dense_sparse_matmul(
1011 out.as_mut(),
1012 lhs,
1013 rhs,
1014 None,
1015 E::faer_one(),
1016 get_global_parallelism(),
1017 );
1018 out
1019 }
1020 }
1021 impl<I: Index> MatMul<SparseColMat<I>> for DenseRow {
1022 type Output = DenseRow;
1023
1024 #[track_caller]
1025 fn mat_mul<
1026 E: ComplexField,
1027 LhsE: Conjugate<Canonical = E>,
1028 RhsE: Conjugate<Canonical = E>,
1029 >(
1030 lhs: KindRef<'_, LhsE, Self>,
1031 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1032 ) -> KindOwn<E, Self::Output> {
1033 let mut out = Row::zeros(rhs.ncols());
1034 sparse::mul::dense_sparse_matmul(
1035 out.as_mut().as_2d_mut(),
1036 lhs.as_2d(),
1037 rhs,
1038 None,
1039 E::faer_one(),
1040 get_global_parallelism(),
1041 );
1042 out
1043 }
1044 }
1045 impl<I: Index> MatMul<SparseRowMat<I>> for Dense {
1046 type Output = Dense;
1047
1048 #[track_caller]
1049 fn mat_mul<
1050 E: ComplexField,
1051 LhsE: Conjugate<Canonical = E>,
1052 RhsE: Conjugate<Canonical = E>,
1053 >(
1054 lhs: KindRef<'_, LhsE, Self>,
1055 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1056 ) -> KindOwn<E, Self::Output> {
1057 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
1058 sparse::mul::sparse_dense_matmul(
1059 out.as_mut().transpose_mut(),
1060 rhs.transpose(),
1061 lhs.transpose(),
1062 None,
1063 E::faer_one(),
1064 get_global_parallelism(),
1065 );
1066 out
1067 }
1068 }
1069 impl<I: Index> MatMul<SparseRowMat<I>> for DenseRow {
1070 type Output = DenseRow;
1071
1072 #[track_caller]
1073 fn mat_mul<
1074 E: ComplexField,
1075 LhsE: Conjugate<Canonical = E>,
1076 RhsE: Conjugate<Canonical = E>,
1077 >(
1078 lhs: KindRef<'_, LhsE, Self>,
1079 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1080 ) -> KindOwn<E, Self::Output> {
1081 let mut out = Row::zeros(rhs.ncols());
1082 sparse::mul::sparse_dense_matmul(
1083 out.as_mut().transpose_mut().as_2d_mut(),
1084 rhs.transpose(),
1085 lhs.transpose().as_2d(),
1086 None,
1087 E::faer_one(),
1088 get_global_parallelism(),
1089 );
1090 out
1091 }
1092 }
1093
1094 impl<I: Index> MatMul<Dense> for SparseColMat<I> {
1095 type Output = Dense;
1096
1097 #[track_caller]
1098 fn mat_mul<
1099 E: ComplexField,
1100 LhsE: Conjugate<Canonical = E>,
1101 RhsE: Conjugate<Canonical = E>,
1102 >(
1103 lhs: KindRef<'_, LhsE, Self>,
1104 rhs: KindRef<'_, RhsE, Dense>,
1105 ) -> KindOwn<E, Self::Output> {
1106 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
1107 sparse::mul::sparse_dense_matmul(
1108 out.as_mut(),
1109 lhs,
1110 rhs,
1111 None,
1112 E::faer_one(),
1113 get_global_parallelism(),
1114 );
1115 out
1116 }
1117 }
1118 impl<I: Index> MatMul<DenseCol> for SparseColMat<I> {
1119 type Output = DenseCol;
1120
1121 #[track_caller]
1122 fn mat_mul<
1123 E: ComplexField,
1124 LhsE: Conjugate<Canonical = E>,
1125 RhsE: Conjugate<Canonical = E>,
1126 >(
1127 lhs: KindRef<'_, LhsE, Self>,
1128 rhs: KindRef<'_, RhsE, DenseCol>,
1129 ) -> KindOwn<E, Self::Output> {
1130 let mut out = Col::zeros(lhs.nrows());
1131 sparse::mul::sparse_dense_matmul(
1132 out.as_mut().as_2d_mut(),
1133 lhs,
1134 rhs.as_2d(),
1135 None,
1136 E::faer_one(),
1137 get_global_parallelism(),
1138 );
1139 out
1140 }
1141 }
1142 impl<I: Index> MatMul<Dense> for SparseRowMat<I> {
1143 type Output = Dense;
1144
1145 #[track_caller]
1146 fn mat_mul<
1147 E: ComplexField,
1148 LhsE: Conjugate<Canonical = E>,
1149 RhsE: Conjugate<Canonical = E>,
1150 >(
1151 lhs: KindRef<'_, LhsE, Self>,
1152 rhs: KindRef<'_, RhsE, Dense>,
1153 ) -> KindOwn<E, Self::Output> {
1154 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
1155 sparse::mul::dense_sparse_matmul(
1156 out.as_mut().transpose_mut(),
1157 rhs.transpose(),
1158 lhs.transpose(),
1159 None,
1160 E::faer_one(),
1161 get_global_parallelism(),
1162 );
1163 out
1164 }
1165 }
1166 impl<I: Index> MatMul<DenseCol> for SparseRowMat<I> {
1167 type Output = DenseCol;
1168
1169 #[track_caller]
1170 fn mat_mul<
1171 E: ComplexField,
1172 LhsE: Conjugate<Canonical = E>,
1173 RhsE: Conjugate<Canonical = E>,
1174 >(
1175 lhs: KindRef<'_, LhsE, Self>,
1176 rhs: KindRef<'_, RhsE, DenseCol>,
1177 ) -> KindOwn<E, Self::Output> {
1178 let mut out = Col::zeros(lhs.nrows());
1179 sparse::mul::dense_sparse_matmul(
1180 out.as_mut().transpose_mut().as_2d_mut(),
1181 rhs.transpose().as_2d(),
1182 lhs.transpose(),
1183 None,
1184 E::faer_one(),
1185 get_global_parallelism(),
1186 );
1187 out
1188 }
1189 }
1190}
1191
1192pub trait MatMulAssign<Rhs: MatrixKind>: MatrixKind {
1194 fn mat_mul_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1196 lhs: KindMut<'_, E, Self>,
1197 rhs: KindRef<'_, RhsE, Rhs>,
1198 );
1199}
1200pub trait MatAddAssign<Rhs: MatrixKind>: MatrixKind {
1202 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1204 lhs: KindMut<'_, E, Self>,
1205 rhs: KindRef<'_, RhsE, Rhs>,
1206 );
1207}
1208pub trait MatSubAssign<Rhs: MatrixKind>: MatrixKind {
1210 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1212 lhs: KindMut<'_, E, Self>,
1213 rhs: KindRef<'_, RhsE, Rhs>,
1214 );
1215}
1216
1217pub trait MatEq<Rhs: MatrixKind>: MatrixKind {
1219 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1221 lhs: KindRef<'_, LhsE, Self>,
1222 rhs: KindRef<'_, RhsE, Rhs>,
1223 ) -> bool;
1224}
1225
1226pub trait MatMul<Rhs: MatrixKind>: MatrixKind {
1228 type Output: MatrixKind;
1230
1231 fn mat_mul<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1233 lhs: KindRef<'_, LhsE, Self>,
1234 rhs: KindRef<'_, RhsE, Rhs>,
1235 ) -> KindOwn<E, Self::Output>;
1236}
1237pub trait MatAdd<Rhs: MatrixKind>: MatrixKind {
1239 type Output: MatrixKind;
1241
1242 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1244 lhs: KindRef<'_, LhsE, Self>,
1245 rhs: KindRef<'_, RhsE, Rhs>,
1246 ) -> KindOwn<E, Self::Output>;
1247}
1248pub trait MatSub<Rhs: MatrixKind>: MatrixKind {
1250 type Output: MatrixKind;
1252
1253 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1255 lhs: KindRef<'_, LhsE, Self>,
1256 rhs: KindRef<'_, RhsE, Rhs>,
1257 ) -> KindOwn<E, Self::Output>;
1258}
1259pub trait MatNeg: MatrixKind {
1261 type Output: MatrixKind;
1263
1264 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1266 where
1267 E::Canonical: ComplexField;
1268}
1269
1270impl<I: Index> MatEq<Perm<I>> for Perm<I> {
1271 #[track_caller]
1272 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1273 lhs: KindRef<'_, LhsE, Self>,
1274 rhs: KindRef<'_, RhsE, Self>,
1275 ) -> bool {
1276 lhs.inner.forward == rhs.inner.forward
1277 }
1278}
1279
1280impl MatEq<DenseCol> for DenseCol {
1281 #[track_caller]
1282 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1283 lhs: KindRef<'_, LhsE, Self>,
1284 rhs: KindRef<'_, RhsE, Self>,
1285 ) -> bool {
1286 lhs.as_2d() == rhs.as_2d()
1287 }
1288}
1289impl MatEq<DenseRow> for DenseRow {
1290 #[track_caller]
1291 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1292 lhs: KindRef<'_, LhsE, Self>,
1293 rhs: KindRef<'_, RhsE, Self>,
1294 ) -> bool {
1295 lhs.as_2d() == rhs.as_2d()
1296 }
1297}
1298
1299impl MatEq<Dense> for Dense {
1300 #[track_caller]
1301 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1302 lhs: KindRef<'_, LhsE, Self>,
1303 rhs: KindRef<'_, RhsE, Self>,
1304 ) -> bool {
1305 if (lhs.nrows(), lhs.ncols()) != (rhs.nrows(), rhs.ncols()) {
1306 return false;
1307 }
1308 let m = lhs.nrows();
1309 let n = lhs.ncols();
1310 for j in 0..n {
1311 for i in 0..m {
1312 if !(lhs.read(i, j).canonicalize() == rhs.read(i, j).canonicalize()) {
1313 return false;
1314 }
1315 }
1316 }
1317
1318 true
1319 }
1320}
1321
1322impl<I: Index> MatEq<SparseColMat<I>> for SparseColMat<I> {
1323 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1324 lhs: KindRef<'_, LhsE, Self>,
1325 rhs: KindRef<'_, RhsE, Self>,
1326 ) -> bool {
1327 if lhs.nrows() != rhs.nrows() || lhs.ncols() != rhs.ncols() {
1328 return false;
1329 }
1330
1331 let n = lhs.ncols();
1332 let mut equal = true;
1333 for j in 0..n {
1334 equal &= lhs.row_indices_of_col_raw(j) == rhs.row_indices_of_col_raw(j);
1335 let lhs_val = SliceGroup::<'_, LhsE>::new(lhs.values_of_col(j));
1336 let rhs_val = SliceGroup::<'_, RhsE>::new(rhs.values_of_col(j));
1337 equal &= lhs_val
1338 .into_ref_iter()
1339 .map(|r| r.read().canonicalize())
1340 .eq(rhs_val.into_ref_iter().map(|r| r.read().canonicalize()))
1341 }
1342
1343 equal
1344 }
1345}
1346
1347impl<I: Index> MatEq<SparseRowMat<I>> for SparseRowMat<I> {
1348 fn mat_eq<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1349 lhs: KindRef<'_, LhsE, Self>,
1350 rhs: KindRef<'_, RhsE, Self>,
1351 ) -> bool {
1352 lhs.transpose() == rhs.transpose()
1353 }
1354}
1355
1356impl MatAdd<DenseCol> for DenseCol {
1357 type Output = DenseCol;
1358
1359 #[track_caller]
1360 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1361 lhs: KindRef<'_, LhsE, Self>,
1362 rhs: KindRef<'_, RhsE, Self>,
1363 ) -> KindOwn<E, Self::Output> {
1364 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1365 let mut out = Col::<E>::zeros(lhs.nrows());
1366 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d(), rhs.as_2d()).for_each(
1367 |unzipped!(mut out, lhs, rhs)| {
1368 out.write(E::faer_add(
1369 lhs.read().canonicalize(),
1370 rhs.read().canonicalize(),
1371 ))
1372 },
1373 );
1374 out
1375 }
1376}
1377impl MatSub<DenseCol> for DenseCol {
1378 type Output = DenseCol;
1379
1380 #[track_caller]
1381 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1382 lhs: KindRef<'_, LhsE, Self>,
1383 rhs: KindRef<'_, RhsE, Self>,
1384 ) -> KindOwn<E, Self::Output> {
1385 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1386 let mut out = Col::<E>::zeros(lhs.nrows());
1387 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d(), rhs.as_2d()).for_each(
1388 |unzipped!(mut out, lhs, rhs)| {
1389 out.write(E::faer_sub(
1390 lhs.read().canonicalize(),
1391 rhs.read().canonicalize(),
1392 ))
1393 },
1394 );
1395 out
1396 }
1397}
1398impl MatAddAssign<DenseCol> for DenseCol {
1399 #[track_caller]
1400 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1401 lhs: KindMut<'_, E, DenseCol>,
1402 rhs: KindRef<'_, RhsE, DenseCol>,
1403 ) {
1404 zipped!(lhs.as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut lhs, rhs)| {
1405 lhs.write(lhs.read().faer_add(rhs.read().canonicalize()))
1406 });
1407 }
1408}
1409impl MatSubAssign<DenseCol> for DenseCol {
1410 #[track_caller]
1411 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1412 lhs: KindMut<'_, E, DenseCol>,
1413 rhs: KindRef<'_, RhsE, DenseCol>,
1414 ) {
1415 zipped!(lhs.as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut lhs, rhs)| {
1416 lhs.write(lhs.read().faer_sub(rhs.read().canonicalize()))
1417 });
1418 }
1419}
1420
1421impl MatNeg for DenseCol {
1422 type Output = DenseCol;
1423
1424 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1425 where
1426 E::Canonical: ComplexField,
1427 {
1428 let mut out = Col::<E::Canonical>::zeros(mat.nrows());
1429 zipped!(out.as_mut().as_2d_mut(), mat.as_2d())
1430 .for_each(|unzipped!(mut out, src)| out.write(src.read().canonicalize().faer_neg()));
1431 out
1432 }
1433}
1434
1435impl MatAdd<DenseRow> for DenseRow {
1436 type Output = DenseRow;
1437
1438 #[track_caller]
1439 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1440 lhs: KindRef<'_, LhsE, Self>,
1441 rhs: KindRef<'_, RhsE, Self>,
1442 ) -> KindOwn<E, Self::Output> {
1443 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1444 let mut out = Row::<E>::zeros(lhs.nrows());
1445 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d(), rhs.as_2d()).for_each(
1446 |unzipped!(mut out, lhs, rhs)| {
1447 out.write(E::faer_add(
1448 lhs.read().canonicalize(),
1449 rhs.read().canonicalize(),
1450 ))
1451 },
1452 );
1453 out
1454 }
1455}
1456impl MatSub<DenseRow> for DenseRow {
1457 type Output = DenseRow;
1458
1459 #[track_caller]
1460 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1461 lhs: KindRef<'_, LhsE, Self>,
1462 rhs: KindRef<'_, RhsE, Self>,
1463 ) -> KindOwn<E, Self::Output> {
1464 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1465 let mut out = Row::<E>::zeros(lhs.nrows());
1466 zipped!(out.as_mut().as_2d_mut(), lhs.as_2d(), rhs.as_2d()).for_each(
1467 |unzipped!(mut out, lhs, rhs)| {
1468 out.write(E::faer_sub(
1469 lhs.read().canonicalize(),
1470 rhs.read().canonicalize(),
1471 ))
1472 },
1473 );
1474 out
1475 }
1476}
1477impl MatAddAssign<DenseRow> for DenseRow {
1478 #[track_caller]
1479 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1480 lhs: KindMut<'_, E, DenseRow>,
1481 rhs: KindRef<'_, RhsE, DenseRow>,
1482 ) {
1483 zipped!(lhs.as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut lhs, rhs)| {
1484 lhs.write(lhs.read().faer_add(rhs.read().canonicalize()))
1485 });
1486 }
1487}
1488impl MatSubAssign<DenseRow> for DenseRow {
1489 #[track_caller]
1490 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1491 lhs: KindMut<'_, E, DenseRow>,
1492 rhs: KindRef<'_, RhsE, DenseRow>,
1493 ) {
1494 zipped!(lhs.as_2d_mut(), rhs.as_2d()).for_each(|unzipped!(mut lhs, rhs)| {
1495 lhs.write(lhs.read().faer_sub(rhs.read().canonicalize()))
1496 });
1497 }
1498}
1499
1500impl MatNeg for DenseRow {
1501 type Output = DenseRow;
1502
1503 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1504 where
1505 E::Canonical: ComplexField,
1506 {
1507 let mut out = Row::<E::Canonical>::zeros(mat.nrows());
1508 zipped!(out.as_mut().as_2d_mut(), mat.as_2d())
1509 .for_each(|unzipped!(mut out, src)| out.write(src.read().canonicalize().faer_neg()));
1510 out
1511 }
1512}
1513
1514impl MatAdd<Dense> for Dense {
1515 type Output = Dense;
1516
1517 #[track_caller]
1518 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1519 lhs: KindRef<'_, LhsE, Self>,
1520 rhs: KindRef<'_, RhsE, Self>,
1521 ) -> KindOwn<E, Self::Output> {
1522 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1523 let mut out = Mat::<E>::zeros(lhs.nrows(), rhs.ncols());
1524 zipped!(out.as_mut(), lhs, rhs).for_each(|unzipped!(mut out, lhs, rhs)| {
1525 out.write(E::faer_add(
1526 lhs.read().canonicalize(),
1527 rhs.read().canonicalize(),
1528 ))
1529 });
1530 out
1531 }
1532}
1533impl MatSub<Dense> for Dense {
1534 type Output = Dense;
1535
1536 #[track_caller]
1537 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1538 lhs: KindRef<'_, LhsE, Self>,
1539 rhs: KindRef<'_, RhsE, Self>,
1540 ) -> KindOwn<E, Self::Output> {
1541 assert!(all(lhs.nrows() == rhs.nrows(), lhs.ncols() == rhs.ncols()));
1542 let mut out = Mat::<E>::zeros(lhs.nrows(), rhs.ncols());
1543 zipped!(out.as_mut(), lhs, rhs).for_each(|unzipped!(mut out, lhs, rhs)| {
1544 out.write(E::faer_sub(
1545 lhs.read().canonicalize(),
1546 rhs.read().canonicalize(),
1547 ))
1548 });
1549 out
1550 }
1551}
1552impl MatAddAssign<Dense> for Dense {
1553 #[track_caller]
1554 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1555 lhs: KindMut<'_, E, Dense>,
1556 rhs: KindRef<'_, RhsE, Dense>,
1557 ) {
1558 zipped!(lhs, rhs).for_each(|unzipped!(mut lhs, rhs)| {
1559 lhs.write(lhs.read().faer_add(rhs.read().canonicalize()))
1560 });
1561 }
1562}
1563impl MatSubAssign<Dense> for Dense {
1564 #[track_caller]
1565 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1566 lhs: KindMut<'_, E, Dense>,
1567 rhs: KindRef<'_, RhsE, Dense>,
1568 ) {
1569 zipped!(lhs, rhs).for_each(|unzipped!(mut lhs, rhs)| {
1570 lhs.write(lhs.read().faer_sub(rhs.read().canonicalize()))
1571 });
1572 }
1573}
1574
1575impl MatNeg for Dense {
1576 type Output = Dense;
1577
1578 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1579 where
1580 E::Canonical: ComplexField,
1581 {
1582 let mut out = Mat::<E::Canonical>::zeros(mat.nrows(), mat.ncols());
1583 zipped!(out.as_mut(), mat)
1584 .for_each(|unzipped!(mut out, src)| out.write(src.read().canonicalize().faer_neg()));
1585 out
1586 }
1587}
1588
1589impl<I: Index> MatAdd<SparseColMat<I>> for SparseColMat<I> {
1590 type Output = SparseColMat<I>;
1591
1592 #[track_caller]
1593 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1594 lhs: KindRef<'_, LhsE, Self>,
1595 rhs: KindRef<'_, RhsE, Self>,
1596 ) -> KindOwn<E, Self::Output> {
1597 crate::sparse::ops::add(lhs, rhs).unwrap()
1598 }
1599}
1600impl<I: Index> MatAdd<SparseRowMat<I>> for SparseRowMat<I> {
1601 type Output = SparseColMat<I>;
1602
1603 #[track_caller]
1604 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1605 lhs: KindRef<'_, LhsE, Self>,
1606 rhs: KindRef<'_, RhsE, Self>,
1607 ) -> KindOwn<E, Self::Output> {
1608 crate::sparse::ops::add(lhs.transpose(), rhs.transpose())
1609 .unwrap()
1610 .into_transpose()
1611 .to_col_major()
1612 .unwrap()
1613 }
1614}
1615impl<I: Index> MatAdd<SparseRowMat<I>> for SparseColMat<I> {
1616 type Output = SparseColMat<I>;
1617
1618 #[track_caller]
1619 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1620 lhs: KindRef<'_, LhsE, Self>,
1621 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1622 ) -> KindOwn<E, Self::Output> {
1623 crate::sparse::ops::add(lhs, rhs.to_col_major().unwrap().as_ref()).unwrap()
1624 }
1625}
1626impl<I: Index> MatAdd<SparseColMat<I>> for SparseRowMat<I> {
1627 type Output = SparseColMat<I>;
1628
1629 #[track_caller]
1630 fn mat_add<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1631 lhs: KindRef<'_, LhsE, Self>,
1632 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1633 ) -> KindOwn<E, Self::Output> {
1634 crate::sparse::ops::add(lhs.to_col_major().unwrap().as_ref(), rhs).unwrap()
1635 }
1636}
1637
1638impl<I: Index> MatSub<SparseColMat<I>> for SparseColMat<I> {
1639 type Output = SparseColMat<I>;
1640
1641 #[track_caller]
1642 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1643 lhs: KindRef<'_, LhsE, Self>,
1644 rhs: KindRef<'_, RhsE, Self>,
1645 ) -> KindOwn<E, Self::Output> {
1646 crate::sparse::ops::sub(lhs, rhs).unwrap()
1647 }
1648}
1649impl<I: Index> MatSub<SparseRowMat<I>> for SparseRowMat<I> {
1650 type Output = SparseColMat<I>;
1651
1652 #[track_caller]
1653 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1654 lhs: KindRef<'_, LhsE, Self>,
1655 rhs: KindRef<'_, RhsE, Self>,
1656 ) -> KindOwn<E, Self::Output> {
1657 crate::sparse::ops::sub(lhs.transpose(), rhs.transpose())
1658 .unwrap()
1659 .into_transpose()
1660 .to_col_major()
1661 .unwrap()
1662 }
1663}
1664impl<I: Index> MatSub<SparseRowMat<I>> for SparseColMat<I> {
1665 type Output = SparseColMat<I>;
1666
1667 #[track_caller]
1668 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1669 lhs: KindRef<'_, LhsE, Self>,
1670 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1671 ) -> KindOwn<E, Self::Output> {
1672 crate::sparse::ops::sub(lhs, rhs.to_col_major().unwrap().as_ref()).unwrap()
1673 }
1674}
1675impl<I: Index> MatSub<SparseColMat<I>> for SparseRowMat<I> {
1676 type Output = SparseColMat<I>;
1677
1678 #[track_caller]
1679 fn mat_sub<E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>>(
1680 lhs: KindRef<'_, LhsE, Self>,
1681 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1682 ) -> KindOwn<E, Self::Output> {
1683 crate::sparse::ops::sub(lhs.to_col_major().unwrap().as_ref(), rhs).unwrap()
1684 }
1685}
1686
1687impl<I: Index> MatNeg for SparseColMat<I> {
1688 type Output = SparseColMat<I>;
1689
1690 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1691 where
1692 E::Canonical: ComplexField,
1693 {
1694 let mut out = mat.to_owned().unwrap();
1695 crate::group_helpers::SliceGroupMut::<E::Canonical>::new(out.as_mut().values_mut())
1696 .into_mut_iter()
1697 .for_each(|mut x| x.write(x.read().faer_neg()));
1698 out
1699 }
1700}
1701
1702impl<I: Index> MatNeg for SparseRowMat<I> {
1703 type Output = SparseColMat<I>;
1704
1705 fn mat_neg<E: Conjugate>(mat: KindRef<'_, E, Self>) -> KindOwn<E::Canonical, Self::Output>
1706 where
1707 E::Canonical: ComplexField,
1708 {
1709 let mut out = mat.to_col_major().unwrap();
1710 crate::group_helpers::SliceGroupMut::<E::Canonical>::new(out.as_mut().values_mut())
1711 .into_mut_iter()
1712 .for_each(|mut x| x.write(x.read().faer_neg()));
1713 out
1714 }
1715}
1716
1717impl<I: Index> MatAddAssign<SparseColMat<I>> for SparseColMat<I> {
1718 #[track_caller]
1719 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1720 lhs: KindMut<'_, E, SparseColMat<I>>,
1721 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1722 ) {
1723 crate::sparse::ops::add_assign(lhs, rhs);
1724 }
1725}
1726impl<I: Index> MatSubAssign<SparseColMat<I>> for SparseColMat<I> {
1727 #[track_caller]
1728 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1729 lhs: KindMut<'_, E, SparseColMat<I>>,
1730 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1731 ) {
1732 crate::sparse::ops::sub_assign(lhs, rhs);
1733 }
1734}
1735
1736impl<I: Index> MatAddAssign<SparseRowMat<I>> for SparseRowMat<I> {
1737 #[track_caller]
1738 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1739 lhs: KindMut<'_, E, SparseRowMat<I>>,
1740 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1741 ) {
1742 crate::sparse::ops::add_assign(lhs.transpose_mut(), rhs.transpose());
1743 }
1744}
1745impl<I: Index> MatSubAssign<SparseRowMat<I>> for SparseRowMat<I> {
1746 #[track_caller]
1747 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1748 lhs: KindMut<'_, E, SparseRowMat<I>>,
1749 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1750 ) {
1751 crate::sparse::ops::sub_assign(lhs.transpose_mut(), rhs.transpose());
1752 }
1753}
1754
1755impl<I: Index> MatAddAssign<SparseColMat<I>> for SparseRowMat<I> {
1756 #[track_caller]
1757 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1758 lhs: KindMut<'_, E, SparseRowMat<I>>,
1759 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1760 ) {
1761 crate::sparse::ops::add_assign(
1762 lhs.transpose_mut(),
1763 rhs.transpose().to_col_major().unwrap().as_ref(),
1764 );
1765 }
1766}
1767impl<I: Index> MatSubAssign<SparseColMat<I>> for SparseRowMat<I> {
1768 #[track_caller]
1769 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1770 lhs: KindMut<'_, E, SparseRowMat<I>>,
1771 rhs: KindRef<'_, RhsE, SparseColMat<I>>,
1772 ) {
1773 crate::sparse::ops::sub_assign(
1774 lhs.transpose_mut(),
1775 rhs.transpose().to_col_major().unwrap().as_ref(),
1776 );
1777 }
1778}
1779
1780impl<I: Index> MatAddAssign<SparseRowMat<I>> for SparseColMat<I> {
1781 #[track_caller]
1782 fn mat_add_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1783 lhs: KindMut<'_, E, SparseColMat<I>>,
1784 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1785 ) {
1786 crate::sparse::ops::add_assign(lhs, rhs.to_col_major().unwrap().as_ref());
1787 }
1788}
1789impl<I: Index> MatSubAssign<SparseRowMat<I>> for SparseColMat<I> {
1790 #[track_caller]
1791 fn mat_sub_assign<E: ComplexField, RhsE: Conjugate<Canonical = E>>(
1792 lhs: KindMut<'_, E, SparseColMat<I>>,
1793 rhs: KindRef<'_, RhsE, SparseRowMat<I>>,
1794 ) {
1795 crate::sparse::ops::sub_assign(lhs, rhs.to_col_major().unwrap().as_ref());
1796 }
1797}
1798
1799#[inline(always)]
1801pub fn scale<E: Entity>(value: E) -> Matrix<inner::Scale<E>> {
1802 Matrix {
1803 inner: inner::Scale(value),
1804 }
1805}
1806
1807const _: () = {
1808 use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
1809
1810 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Mul<&Matrix<Rhs>> for &Matrix<Lhs>
1811 where
1812 Lhs::Elem: Conjugate,
1813 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1814 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1815 Lhs::Kind: MatMul<Rhs::Kind>,
1816 {
1817 type Output =
1818 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatMul<Rhs::Kind>>::Output>;
1819
1820 #[track_caller]
1821 fn mul(self, rhs: &Matrix<Rhs>) -> Self::Output {
1822 <Lhs::Kind as MatMul<Rhs::Kind>>::mat_mul(
1823 GenericMatrix::as_ref(self),
1824 GenericMatrix::as_ref(rhs),
1825 )
1826 }
1827 }
1828 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Mul<&Matrix<Rhs>> for Matrix<Lhs>
1829 where
1830 Lhs::Elem: Conjugate,
1831 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1832 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1833 Lhs::Kind: MatMul<Rhs::Kind>,
1834 {
1835 type Output =
1836 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatMul<Rhs::Kind>>::Output>;
1837
1838 #[track_caller]
1839 fn mul(self, rhs: &Matrix<Rhs>) -> Self::Output {
1840 &self * rhs
1841 }
1842 }
1843 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Mul<Matrix<Rhs>> for &Matrix<Lhs>
1844 where
1845 Lhs::Elem: Conjugate,
1846 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1847 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1848 Lhs::Kind: MatMul<Rhs::Kind>,
1849 {
1850 type Output =
1851 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatMul<Rhs::Kind>>::Output>;
1852
1853 #[track_caller]
1854 fn mul(self, rhs: Matrix<Rhs>) -> Self::Output {
1855 self * &rhs
1856 }
1857 }
1858
1859 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Mul<Matrix<Rhs>> for Matrix<Lhs>
1860 where
1861 Lhs::Elem: Conjugate,
1862 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1863 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1864 Lhs::Kind: MatMul<Rhs::Kind>,
1865 {
1866 type Output =
1867 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatMul<Rhs::Kind>>::Output>;
1868
1869 #[track_caller]
1870 fn mul(self, rhs: Matrix<Rhs>) -> Self::Output {
1871 &self * &rhs
1872 }
1873 }
1874
1875 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Add<&Matrix<Rhs>> for &Matrix<Lhs>
1876 where
1877 Lhs::Elem: Conjugate,
1878 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1879 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1880 Lhs::Kind: MatAdd<Rhs::Kind>,
1881 {
1882 type Output =
1883 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatAdd<Rhs::Kind>>::Output>;
1884
1885 #[track_caller]
1886 fn add(self, rhs: &Matrix<Rhs>) -> Self::Output {
1887 <Lhs::Kind as MatAdd<Rhs::Kind>>::mat_add(
1888 GenericMatrix::as_ref(self),
1889 GenericMatrix::as_ref(rhs),
1890 )
1891 }
1892 }
1893 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Add<&Matrix<Rhs>> for Matrix<Lhs>
1894 where
1895 Lhs::Elem: Conjugate,
1896 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1897 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1898 Lhs::Kind: MatAdd<Rhs::Kind>,
1899 {
1900 type Output =
1901 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatAdd<Rhs::Kind>>::Output>;
1902
1903 #[track_caller]
1904 fn add(self, rhs: &Matrix<Rhs>) -> Self::Output {
1905 &self + rhs
1906 }
1907 }
1908 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Add<Matrix<Rhs>> for &Matrix<Lhs>
1909 where
1910 Lhs::Elem: Conjugate,
1911 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1912 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1913 Lhs::Kind: MatAdd<Rhs::Kind>,
1914 {
1915 type Output =
1916 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatAdd<Rhs::Kind>>::Output>;
1917
1918 #[track_caller]
1919 fn add(self, rhs: Matrix<Rhs>) -> Self::Output {
1920 self + &rhs
1921 }
1922 }
1923 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Add<Matrix<Rhs>> for Matrix<Lhs>
1924 where
1925 Lhs::Elem: Conjugate,
1926 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1927 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1928 Lhs::Kind: MatAdd<Rhs::Kind>,
1929 {
1930 type Output =
1931 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatAdd<Rhs::Kind>>::Output>;
1932
1933 #[track_caller]
1934 fn add(self, rhs: Matrix<Rhs>) -> Self::Output {
1935 &self + &rhs
1936 }
1937 }
1938
1939 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Sub<&Matrix<Rhs>> for &Matrix<Lhs>
1940 where
1941 Lhs::Elem: Conjugate,
1942 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1943 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1944 Lhs::Kind: MatSub<Rhs::Kind>,
1945 {
1946 type Output =
1947 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatSub<Rhs::Kind>>::Output>;
1948
1949 #[track_caller]
1950 fn sub(self, rhs: &Matrix<Rhs>) -> Self::Output {
1951 <Lhs::Kind as MatSub<Rhs::Kind>>::mat_sub(
1952 GenericMatrix::as_ref(self),
1953 GenericMatrix::as_ref(rhs),
1954 )
1955 }
1956 }
1957
1958 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Sub<&Matrix<Rhs>> for Matrix<Lhs>
1959 where
1960 Lhs::Elem: Conjugate,
1961 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1962 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1963 Lhs::Kind: MatSub<Rhs::Kind>,
1964 {
1965 type Output =
1966 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatSub<Rhs::Kind>>::Output>;
1967
1968 #[track_caller]
1969 fn sub(self, rhs: &Matrix<Rhs>) -> Self::Output {
1970 &self - rhs
1971 }
1972 }
1973 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Sub<Matrix<Rhs>> for &Matrix<Lhs>
1974 where
1975 Lhs::Elem: Conjugate,
1976 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1977 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1978 Lhs::Kind: MatSub<Rhs::Kind>,
1979 {
1980 type Output =
1981 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatSub<Rhs::Kind>>::Output>;
1982
1983 #[track_caller]
1984 fn sub(self, rhs: Matrix<Rhs>) -> Self::Output {
1985 self - &rhs
1986 }
1987 }
1988 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> Sub<Matrix<Rhs>> for Matrix<Lhs>
1989 where
1990 Lhs::Elem: Conjugate,
1991 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
1992 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
1993 Lhs::Kind: MatSub<Rhs::Kind>,
1994 {
1995 type Output =
1996 KindOwn<<Lhs::Elem as Conjugate>::Canonical, <Lhs::Kind as MatSub<Rhs::Kind>>::Output>;
1997
1998 #[track_caller]
1999 fn sub(self, rhs: Matrix<Rhs>) -> Self::Output {
2000 &self - &rhs
2001 }
2002 }
2003
2004 impl<Mat: GenericMatrix> Neg for &Matrix<Mat>
2005 where
2006 Mat::Elem: Conjugate,
2007 <Mat::Elem as Conjugate>::Canonical: ComplexField,
2008 Mat::Kind: MatNeg,
2009 {
2010 type Output = KindOwn<<Mat::Elem as Conjugate>::Canonical, <Mat::Kind as MatNeg>::Output>;
2011 fn neg(self) -> Self::Output {
2012 <Mat::Kind as MatNeg>::mat_neg(GenericMatrix::as_ref(self))
2013 }
2014 }
2015 impl<Mat: GenericMatrix> Neg for Matrix<Mat>
2016 where
2017 Mat::Elem: Conjugate,
2018 <Mat::Elem as Conjugate>::Canonical: ComplexField,
2019 Mat::Kind: MatNeg,
2020 {
2021 type Output = KindOwn<<Mat::Elem as Conjugate>::Canonical, <Mat::Kind as MatNeg>::Output>;
2022 fn neg(self) -> Self::Output {
2023 -&self
2024 }
2025 }
2026
2027 impl<Lhs: GenericMatrix, Rhs: GenericMatrix> PartialEq<Matrix<Rhs>> for Matrix<Lhs>
2028 where
2029 Lhs::Elem: Conjugate,
2030 Rhs::Elem: Conjugate<Canonical = <Lhs::Elem as Conjugate>::Canonical>,
2031 <Lhs::Elem as Conjugate>::Canonical: ComplexField,
2032 Lhs::Kind: MatEq<Rhs::Kind>,
2033 {
2034 fn eq(&self, rhs: &Matrix<Rhs>) -> bool {
2035 <Lhs::Kind as MatEq<Rhs::Kind>>::mat_eq(
2036 GenericMatrix::as_ref(self),
2037 GenericMatrix::as_ref(rhs),
2038 )
2039 }
2040 }
2041
2042 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> MulAssign<&Matrix<Rhs>> for Matrix<Lhs>
2043 where
2044 Lhs::Elem: ComplexField,
2045 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2046 Lhs::Kind: MatMulAssign<Rhs::Kind>,
2047 {
2048 #[track_caller]
2049 fn mul_assign(&mut self, rhs: &Matrix<Rhs>) {
2050 <Lhs::Kind as MatMulAssign<Rhs::Kind>>::mat_mul_assign(
2051 GenericMatrixMut::as_mut(self),
2052 GenericMatrix::as_ref(rhs),
2053 );
2054 }
2055 }
2056 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> MulAssign<Matrix<Rhs>> for Matrix<Lhs>
2057 where
2058 Lhs::Elem: ComplexField,
2059 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2060 Lhs::Kind: MatMulAssign<Rhs::Kind>,
2061 {
2062 #[track_caller]
2063 fn mul_assign(&mut self, rhs: Matrix<Rhs>) {
2064 *self *= &rhs;
2065 }
2066 }
2067
2068 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> AddAssign<&Matrix<Rhs>> for Matrix<Lhs>
2069 where
2070 Lhs::Elem: ComplexField,
2071 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2072 Lhs::Kind: MatAddAssign<Rhs::Kind>,
2073 {
2074 #[track_caller]
2075 fn add_assign(&mut self, rhs: &Matrix<Rhs>) {
2076 <Lhs::Kind as MatAddAssign<Rhs::Kind>>::mat_add_assign(
2077 GenericMatrixMut::as_mut(self),
2078 GenericMatrix::as_ref(rhs),
2079 );
2080 }
2081 }
2082 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> AddAssign<Matrix<Rhs>> for Matrix<Lhs>
2083 where
2084 Lhs::Elem: ComplexField,
2085 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2086 Lhs::Kind: MatAddAssign<Rhs::Kind>,
2087 {
2088 #[track_caller]
2089 fn add_assign(&mut self, rhs: Matrix<Rhs>) {
2090 *self += &rhs;
2091 }
2092 }
2093
2094 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> SubAssign<&Matrix<Rhs>> for Matrix<Lhs>
2095 where
2096 Lhs::Elem: ComplexField,
2097 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2098 Lhs::Kind: MatSubAssign<Rhs::Kind>,
2099 {
2100 #[track_caller]
2101 fn sub_assign(&mut self, rhs: &Matrix<Rhs>) {
2102 <Lhs::Kind as MatSubAssign<Rhs::Kind>>::mat_sub_assign(
2103 GenericMatrixMut::as_mut(self),
2104 GenericMatrix::as_ref(rhs),
2105 );
2106 }
2107 }
2108 impl<Lhs: GenericMatrixMut, Rhs: GenericMatrix> SubAssign<Matrix<Rhs>> for Matrix<Lhs>
2109 where
2110 Lhs::Elem: ComplexField,
2111 Rhs::Elem: Conjugate<Canonical = Lhs::Elem>,
2112 Lhs::Kind: MatSubAssign<Rhs::Kind>,
2113 {
2114 #[track_caller]
2115 fn sub_assign(&mut self, rhs: Matrix<Rhs>) {
2116 *self -= &rhs;
2117 }
2118 }
2119};
2120
2121#[cfg(test)]
2122#[allow(non_snake_case)]
2123mod test {
2124 use crate::{
2125 assert, mat,
2126 permutation::{Permutation, PermutationRef},
2127 Col, Mat, Row,
2128 };
2129 use assert_approx_eq::assert_approx_eq;
2130
2131 fn matrices() -> (Mat<f64>, Mat<f64>) {
2132 let A = mat![[2.8, -3.3], [-1.7, 5.2], [4.6, -8.3],];
2133
2134 let B = mat![[-7.9, 8.3], [4.7, -3.2], [3.8, -5.2],];
2135 (A, B)
2136 }
2137
2138 #[test]
2139 #[should_panic]
2140 fn test_adding_matrices_of_different_sizes_should_panic() {
2141 let A = mat![[1.0, 2.0], [3.0, 4.0]];
2142 let B = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
2143 _ = A + B;
2144 }
2145
2146 #[test]
2147 #[should_panic]
2148 fn test_subtracting_two_matrices_of_different_sizes_should_panic() {
2149 let A = mat![[1.0, 2.0], [3.0, 4.0]];
2150 let B = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
2151 _ = A - B;
2152 }
2153
2154 #[test]
2155 fn test_add() {
2156 let (A, B) = matrices();
2157
2158 let expected = mat![[-5.1, 5.0], [3.0, 2.0], [8.4, -13.5],];
2159
2160 assert_matrix_approx_eq(A.as_ref() + B.as_ref(), &expected);
2161 assert_matrix_approx_eq(&A + &B, &expected);
2162 assert_matrix_approx_eq(A.as_ref() + &B, &expected);
2163 assert_matrix_approx_eq(&A + B.as_ref(), &expected);
2164 assert_matrix_approx_eq(A.as_ref() + B.clone(), &expected);
2165 assert_matrix_approx_eq(&A + B.clone(), &expected);
2166 assert_matrix_approx_eq(A.clone() + B.as_ref(), &expected);
2167 assert_matrix_approx_eq(A.clone() + &B, &expected);
2168 assert_matrix_approx_eq(A + B, &expected);
2169 }
2170
2171 #[test]
2172 fn test_sub() {
2173 let (A, B) = matrices();
2174
2175 let expected = mat![[10.7, -11.6], [-6.4, 8.4], [0.8, -3.1],];
2176
2177 assert_matrix_approx_eq(A.as_ref() - B.as_ref(), &expected);
2178 assert_matrix_approx_eq(&A - &B, &expected);
2179 assert_matrix_approx_eq(A.as_ref() - &B, &expected);
2180 assert_matrix_approx_eq(&A - B.as_ref(), &expected);
2181 assert_matrix_approx_eq(A.as_ref() - B.clone(), &expected);
2182 assert_matrix_approx_eq(&A - B.clone(), &expected);
2183 assert_matrix_approx_eq(A.clone() - B.as_ref(), &expected);
2184 assert_matrix_approx_eq(A.clone() - &B, &expected);
2185 assert_matrix_approx_eq(A - B, &expected);
2186 }
2187
2188 #[test]
2189 fn test_neg() {
2190 let (A, _) = matrices();
2191
2192 let expected = mat![[-2.8, 3.3], [1.7, -5.2], [-4.6, 8.3],];
2193
2194 assert_eq!(-A, expected);
2195 }
2196
2197 #[test]
2198 fn test_scalar_mul() {
2199 use crate::scale;
2200
2201 let (A, _) = matrices();
2202 let scale = scale(3.0);
2203 let expected = Mat::from_fn(A.nrows(), A.ncols(), |i, j| A.read(i, j) * scale.value());
2204
2205 {
2206 assert_matrix_approx_eq(A.as_ref() * scale, &expected);
2207 assert_matrix_approx_eq(&A * scale, &expected);
2208 assert_matrix_approx_eq(A.as_ref() * scale, &expected);
2209 assert_matrix_approx_eq(&A * scale, &expected);
2210 assert_matrix_approx_eq(A.as_ref() * scale, &expected);
2211 assert_matrix_approx_eq(&A * scale, &expected);
2212 assert_matrix_approx_eq(A.clone() * scale, &expected);
2213 assert_matrix_approx_eq(A.clone() * scale, &expected);
2214 assert_matrix_approx_eq(A * scale, &expected);
2215 }
2216
2217 let (A, _) = matrices();
2218 {
2219 assert_matrix_approx_eq(scale * A.as_ref(), &expected);
2220 assert_matrix_approx_eq(scale * &A, &expected);
2221 assert_matrix_approx_eq(scale * A.as_ref(), &expected);
2222 assert_matrix_approx_eq(scale * &A, &expected);
2223 assert_matrix_approx_eq(scale * A.as_ref(), &expected);
2224 assert_matrix_approx_eq(scale * &A, &expected);
2225 assert_matrix_approx_eq(scale * A.clone(), &expected);
2226 assert_matrix_approx_eq(scale * A.clone(), &expected);
2227 assert_matrix_approx_eq(scale * A, &expected);
2228 }
2229 }
2230
2231 #[test]
2232 fn test_diag_mul() {
2233 let (A, _) = matrices();
2234 let diag_left = mat![[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]];
2235 let diag_right = mat![[4.0, 0.0], [0.0, 5.0]];
2236
2237 assert!(&diag_left * &A == diag_left.diagonal() * &A);
2238 assert!(&A * &diag_right == &A * diag_right.diagonal());
2239 }
2240
2241 #[test]
2242 fn test_perm_mul() {
2243 let A = Mat::from_fn(6, 5, |i, j| (j + 5 * i) as f64);
2244 let pl = Permutation::<usize, f64>::new_checked(
2245 Box::new([5, 1, 4, 0, 2, 3]),
2246 Box::new([3, 1, 4, 5, 2, 0]),
2247 );
2248 let pr = Permutation::<usize, f64>::new_checked(
2249 Box::new([1, 4, 0, 2, 3]),
2250 Box::new([2, 0, 3, 4, 1]),
2251 );
2252
2253 let perm_left = mat![
2254 [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
2255 [0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
2256 [0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
2257 [1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
2258 [0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
2259 [0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
2260 ];
2261 let perm_right = mat![
2262 [0.0, 1.0, 0.0, 0.0, 0.0],
2263 [0.0, 0.0, 0.0, 0.0, 1.0],
2264 [1.0, 0.0, 0.0, 0.0, 0.0],
2265 [0.0, 0.0, 1.0, 0.0, 0.0],
2266 [0.0, 0.0, 0.0, 1.0, 0.0],
2267 ];
2268
2269 assert!(
2270 &pl * pl.as_ref().inverse()
2271 == PermutationRef::<'_, usize, f64>::new_checked(
2272 &[0, 1, 2, 3, 4, 5],
2273 &[0, 1, 2, 3, 4, 5],
2274 )
2275 );
2276 assert!(&perm_left * &A == &pl * &A);
2277 assert!(&A * &perm_right == &A * &pr);
2278 }
2279
2280 #[test]
2281 fn test_matmul_col_row() {
2282 let A = Col::from_fn(6, |i| i as f64);
2283 let B = Row::from_fn(6, |j| (5 * j + 1) as f64);
2284
2285 assert_eq!(&A * &B, A.as_ref().as_2d() * B.as_ref().as_2d());
2287 assert_eq!(
2289 &B * &A,
2290 (B.as_ref().as_2d() * A.as_ref().as_2d()).read(0, 0),
2291 );
2292 }
2293
2294 fn assert_matrix_approx_eq(given: Mat<f64>, expected: &Mat<f64>) {
2295 assert_eq!(given.nrows(), expected.nrows());
2296 assert_eq!(given.ncols(), expected.ncols());
2297 for i in 0..given.nrows() {
2298 for j in 0..given.ncols() {
2299 assert_approx_eq!(given.read(i, j), expected.read(i, j));
2300 }
2301 }
2302 }
2303}