1use crate::internal_prelude::*;
6use crate::{Scale, assert, col, diag, mat, perm, row};
7use core::ops::{
8 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
9};
10extern crate alloc;
11macro_rules! impl_binop {
12 (
13 { $(impl <$($ty_param:ident $(: $bound:tt)?),* $(,)?> $trait:ident <$rhs:ty > for
14 $lhs:ty { type Output = $out:ty; fn $name:ident ($self:ident, $rhs_:ident : _
15 $(,)?) $block:block })* }
16 ) => {
17 $(impl <$($ty_param $(: $bound)?,)*> $trait <&$rhs > for &$lhs { type Output =
18 $out; #[track_caller] fn $name ($self, $rhs_ : &$rhs) -> Self::Output $block }
19 impl <$($ty_param $(: $bound)?,)*> $trait <$rhs > for $lhs { type Output = $out;
20 #[track_caller] fn $name ($self, $rhs_ : $rhs) -> Self::Output { $trait ::$name
21 (&$self, &$rhs_) } } impl <$($ty_param $(: $bound)?,)*> $trait <$rhs > for &$lhs
22 { type Output = $out; #[track_caller] fn $name ($self, $rhs_ : $rhs) ->
23 Self::Output { $trait ::$name ($self, &$rhs_) } } impl <$($ty_param $(:
24 $bound)?,)*> $trait <&$rhs > for $lhs { type Output = $out; #[track_caller] fn
25 $name ($self, $rhs_ : &$rhs) -> Self::Output { $trait ::$name (&$self, $rhs_) }
26 })*
27 };
28}
29macro_rules! impl_op {
30 (
31 { $(impl <$($ty_param:ident $(: $bound:tt)?),* $(,)?> $trait:ident for $lhs:ty {
32 type Output = $out:ty; fn $name:ident ($self:ident $(,)?) $block:block })* }
33 ) => {
34 $(impl <$($ty_param $(: $bound)?,)*> $trait for &$lhs { type Output = $out;
35 #[track_caller] fn $name ($self) -> Self::Output $block } impl <$($ty_param $(:
36 $bound)?,)*> $trait for $lhs { type Output = $out; #[track_caller] fn $name
37 ($self) -> Self::Output { $trait ::$name (&$self) } })*
38 };
39}
40macro_rules! impl_op_assign {
41 (
42 { $(impl <$($ty_param:ident $(: $bound:tt)?),* $(,)?> $trait:ident <$rhs:ty > for
43 $lhs:ty { fn $name:ident (& mut $self:ident, $rhs_:ident : _ $(,)?) $block:block
44 })* }
45 ) => {
46 $(impl <$($ty_param $(: $bound)?,)*> $trait <&$rhs > for $lhs { #[track_caller]
47 fn $name (& mut $self, $rhs_ : &$rhs) $block } impl <$($ty_param $(: $bound)?,)*>
48 $trait <$rhs > for $lhs { #[track_caller] fn $name (& mut $self, $rhs_ : $rhs) {
49 $trait ::$name ($self, &$rhs_) } })*
50 };
51}
52impl<
53 LT: PartialEq<RT>,
54 LRows: Shape,
55 LCols: Shape,
56 LRStride: Stride,
57 LCStride: Stride,
58 RT,
59 RRows: Shape,
60 RCols: Shape,
61 RRStride: Stride,
62 RCStride: Stride,
63 L: for<'a> Reborrow<
64 'a,
65 Target = mat::Ref<'a, LT, LRows, LCols, LRStride, LCStride>,
66 >,
67 R: for<'a> Reborrow<
68 'a,
69 Target = mat::Ref<'a, RT, RRows, RCols, RRStride, RCStride>,
70 >,
71> PartialEq<mat::generic::Mat<R>> for mat::generic::Mat<L>
72{
73 fn eq(&self, other: &mat::generic::Mat<R>) -> bool {
74 fn imp<LT: PartialEq<RT>, RT>(
75 l: MatRef<'_, LT>,
76 r: MatRef<'_, RT>,
77 ) -> bool {
78 if l.nrows() != r.nrows() {
79 return false;
80 }
81 with_dim!(M, l.nrows());
82 with_dim!(N, l.ncols());
83 let l = l.as_shape(M, N);
84 let r = r.as_shape(M, N);
85 for j in N.indices() {
86 for i in M.indices() {
87 if l[(i, j)] != r[(i, j)] {
88 return false;
89 }
90 }
91 }
92 true
93 }
94 imp(
95 self.rb().as_dyn().as_dyn_stride(),
96 other.rb().as_dyn().as_dyn_stride(),
97 )
98 }
99}
100impl<
101 LT: PartialEq<RT>,
102 LRows: Shape,
103 LRStride: Stride,
104 RT,
105 RRows: Shape,
106 RRStride: Stride,
107 L: for<'a> Reborrow<'a, Target = col::Ref<'a, LT, LRows, LRStride>>,
108 R: for<'a> Reborrow<'a, Target = col::Ref<'a, RT, RRows, RRStride>>,
109> PartialEq<col::generic::Col<R>> for col::generic::Col<L>
110{
111 fn eq(&self, other: &col::generic::Col<R>) -> bool {
112 fn imp<LT: PartialEq<RT>, RT>(
113 l: ColRef<'_, LT>,
114 r: ColRef<'_, RT>,
115 ) -> bool {
116 if l.nrows() != r.nrows() {
117 return false;
118 }
119 with_dim!(N, l.nrows());
120 let l = l.as_row_shape(N);
121 let r = r.as_row_shape(N);
122 for i in N.indices() {
123 if l[i] != r[i] {
124 return false;
125 }
126 }
127 true
128 }
129 imp(
130 self.rb().as_dyn_rows().as_dyn_stride(),
131 other.rb().as_dyn_rows().as_dyn_stride(),
132 )
133 }
134}
135impl<
136 LT: PartialEq<RT>,
137 LCols: Shape,
138 LCStride: Stride,
139 RT,
140 RCols: Shape,
141 RCStride: Stride,
142 L: for<'a> Reborrow<'a, Target = row::Ref<'a, LT, LCols, LCStride>>,
143 R: for<'a> Reborrow<'a, Target = row::Ref<'a, RT, RCols, RCStride>>,
144> PartialEq<row::generic::Row<R>> for row::generic::Row<L>
145{
146 fn eq(&self, other: &row::generic::Row<R>) -> bool {
147 self.rb().transpose() == other.rb().transpose()
148 }
149}
150impl<
151 LT: PartialEq<RT>,
152 LDim: Shape,
153 LStride: Stride,
154 RT,
155 RDim: Shape,
156 RStride: Stride,
157 L: for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, LDim, LStride>>,
158 R: for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, RDim, RStride>>,
159> PartialEq<diag::generic::Diag<R>> for diag::generic::Diag<L>
160{
161 fn eq(&self, other: &diag::generic::Diag<R>) -> bool {
162 self.rb().column_vector() == other.rb().column_vector()
163 }
164}
165impl<
166 LI: Index,
167 LN: Shape,
168 RI: Index,
169 RN: Shape,
170 L: for<'a> Reborrow<'a, Target = perm::Ref<'a, LI, LN>>,
171 R: for<'a> Reborrow<'a, Target = perm::Ref<'a, RI, RN>>,
172> PartialEq<perm::generic::Perm<R>> for perm::generic::Perm<L>
173where
174 LN::Idx<LI>: PartialEq<RN::Idx<RI>>,
175{
176 #[inline]
177 fn eq(&self, other: &perm::generic::Perm<R>) -> bool {
178 self.rb().arrays().0 == other.rb().arrays().0
179 }
180}
181impl_op_assign!({
182 impl<
183 T: ComplexField,
184 Rows: Shape,
185 Cols: Shape,
186 LRStride: Stride,
187 LCStride: Stride,
188 RT: (Conjugate<Canonical = T>),
189 RRStride: Stride,
190 RCStride: Stride,
191 L: (for<'a> ReborrowMut<
192 'a,
193 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
194 >),
195 R: (for<'a> Reborrow<
196 'a,
197 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
198 >),
199 > SubAssign<mat::generic::Mat<R>> for mat::generic::Mat<L>
200 {
201 fn sub_assign(&mut self, rhs: _) {
202 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
203 lhs: MatMut<'_, T>,
204 rhs: MatRef<'_, RT>,
205 ) {
206 zip!(lhs, rhs).for_each(sub_assign_fn::<T, RT>())
207 }
208 let lhs = self.rb_mut();
209 imp(
210 lhs.as_dyn_mut().as_dyn_stride_mut(),
211 rhs.rb().as_dyn().as_dyn_stride(),
212 );
213 }
214 }
215 impl<
216 T: ComplexField,
217 Rows: Shape,
218 LRStride: Stride,
219 RT: (Conjugate<Canonical = T>),
220 RRStride: Stride,
221 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
222 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
223 > SubAssign<col::generic::Col<R>> for col::generic::Col<L>
224 {
225 fn sub_assign(&mut self, rhs: _) {
226 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
227 lhs: ColMut<'_, T>,
228 rhs: ColRef<'_, RT>,
229 ) {
230 zip!(lhs, rhs).for_each(sub_assign_fn::<T, RT>())
231 }
232 let lhs = self.rb_mut();
233 imp(
234 lhs.as_dyn_rows_mut().as_dyn_stride_mut(),
235 rhs.rb().as_dyn_rows().as_dyn_stride(),
236 );
237 }
238 }
239 impl<
240 T: ComplexField,
241 Cols: Shape,
242 LCStride: Stride,
243 RT: (Conjugate<Canonical = T>),
244 RCStride: Stride,
245 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
246 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
247 > SubAssign<row::generic::Row<R>> for row::generic::Row<L>
248 {
249 fn sub_assign(&mut self, rhs: _) {
250 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
251 lhs: RowMut<'_, T>,
252 rhs: RowRef<'_, RT>,
253 ) {
254 SubAssign::sub_assign(
255 &mut lhs.transpose_mut(),
256 &rhs.transpose(),
257 )
258 }
259 let lhs = self.rb_mut();
260 imp(
261 lhs.as_dyn_cols_mut().as_dyn_stride_mut(),
262 rhs.rb().as_dyn_cols().as_dyn_stride(),
263 );
264 }
265 }
266 impl<
267 T: ComplexField,
268 Dim: Shape,
269 LStride: Stride,
270 RT: (Conjugate<Canonical = T>),
271 RStride: Stride,
272 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Dim, LStride>>),
273 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
274 > SubAssign<diag::generic::Diag<R>> for diag::generic::Diag<L>
275 {
276 fn sub_assign(&mut self, rhs: _) {
277 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
278 lhs: ColMut<'_, T>,
279 rhs: ColRef<'_, RT>,
280 ) {
281 SubAssign::sub_assign(&mut { lhs }, &rhs)
282 }
283 let lhs = self.rb_mut();
284 imp(
285 lhs.column_vector_mut()
286 .as_dyn_rows_mut()
287 .as_dyn_stride_mut(),
288 rhs.rb().column_vector().as_dyn_rows().as_dyn_stride(),
289 );
290 }
291 }
292});
293impl_op_assign!({
294 impl<
295 T: ComplexField,
296 Rows: Shape,
297 Cols: Shape,
298 LRStride: Stride,
299 LCStride: Stride,
300 RT: (Conjugate<Canonical = T>),
301 RRStride: Stride,
302 RCStride: Stride,
303 L: (for<'a> ReborrowMut<
304 'a,
305 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
306 >),
307 R: (for<'a> Reborrow<
308 'a,
309 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
310 >),
311 > AddAssign<mat::generic::Mat<R>> for mat::generic::Mat<L>
312 {
313 fn add_assign(&mut self, rhs: _) {
314 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
315 lhs: MatMut<'_, T>,
316 rhs: MatRef<'_, RT>,
317 ) {
318 zip!(lhs, rhs).for_each(add_assign_fn::<T, RT>())
319 }
320 let lhs = self.rb_mut();
321 imp(
322 lhs.as_dyn_mut().as_dyn_stride_mut(),
323 rhs.rb().as_dyn().as_dyn_stride(),
324 );
325 }
326 }
327 impl<
328 T: ComplexField,
329 Rows: Shape,
330 LRStride: Stride,
331 RT: (Conjugate<Canonical = T>),
332 RRStride: Stride,
333 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
334 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
335 > AddAssign<col::generic::Col<R>> for col::generic::Col<L>
336 {
337 fn add_assign(&mut self, rhs: _) {
338 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
339 lhs: ColMut<'_, T>,
340 rhs: ColRef<'_, RT>,
341 ) {
342 zip!(lhs, rhs).for_each(add_assign_fn::<T, RT>())
343 }
344 let lhs = self.rb_mut();
345 imp(
346 lhs.as_dyn_rows_mut().as_dyn_stride_mut(),
347 rhs.rb().as_dyn_rows().as_dyn_stride(),
348 );
349 }
350 }
351 impl<
352 T: ComplexField,
353 Cols: Shape,
354 LCStride: Stride,
355 RT: (Conjugate<Canonical = T>),
356 RCStride: Stride,
357 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
358 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
359 > AddAssign<row::generic::Row<R>> for row::generic::Row<L>
360 {
361 fn add_assign(&mut self, rhs: _) {
362 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
363 lhs: RowMut<'_, T>,
364 rhs: RowRef<'_, RT>,
365 ) {
366 AddAssign::add_assign(
367 &mut lhs.transpose_mut(),
368 &rhs.transpose(),
369 )
370 }
371 let lhs = self.rb_mut();
372 imp(
373 lhs.as_dyn_cols_mut().as_dyn_stride_mut(),
374 rhs.rb().as_dyn_cols().as_dyn_stride(),
375 );
376 }
377 }
378 impl<
379 T: ComplexField,
380 Dim: Shape,
381 LStride: Stride,
382 RT: (Conjugate<Canonical = T>),
383 RStride: Stride,
384 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Dim, LStride>>),
385 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
386 > AddAssign<diag::generic::Diag<R>> for diag::generic::Diag<L>
387 {
388 fn add_assign(&mut self, rhs: _) {
389 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
390 lhs: ColMut<'_, T>,
391 rhs: ColRef<'_, RT>,
392 ) {
393 AddAssign::add_assign(&mut { lhs }, &rhs)
394 }
395 let lhs = self.rb_mut();
396 imp(
397 lhs.column_vector_mut()
398 .as_dyn_rows_mut()
399 .as_dyn_stride_mut(),
400 rhs.rb().column_vector().as_dyn_rows().as_dyn_stride(),
401 );
402 }
403 }
404});
405impl_binop!({
406 impl<
407 T: ComplexField,
408 Rows: Shape,
409 Cols: Shape,
410 LT: (Conjugate<Canonical = T>),
411 LRStride: Stride,
412 LCStride: Stride,
413 RT: (Conjugate<Canonical = T>),
414 RRStride: Stride,
415 RCStride: Stride,
416 L: (for<'a> Reborrow<
417 'a,
418 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
419 >),
420 R: (for<'a> Reborrow<
421 'a,
422 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
423 >),
424 > Add<mat::generic::Mat<R>> for mat::generic::Mat<L>
425 {
426 type Output = Mat<T, Rows, Cols>;
427
428 fn add(self, rhs: _) {
429 #[track_caller]
430 fn imp<
431 T: ComplexField,
432 LT: Conjugate<Canonical = T>,
433 RT: Conjugate<Canonical = T>,
434 >(
435 lhs: MatRef<'_, LT>,
436 rhs: MatRef<'_, RT>,
437 ) -> Mat<T> {
438 assert!(all(
439 lhs.nrows() == rhs.nrows(),
440 lhs.ncols() == rhs.ncols()
441 ));
442 zip!(lhs, rhs).map(add_fn::<LT, RT>())
443 }
444 let lhs = self.rb();
445 imp(
446 lhs.as_dyn().as_dyn_stride(),
447 rhs.rb().as_dyn().as_dyn_stride(),
448 )
449 .into_shape(lhs.nrows(), lhs.ncols())
450 }
451 }
452 impl<
453 T: ComplexField,
454 Rows: Shape,
455 LT: (Conjugate<Canonical = T>),
456 LRStride: Stride,
457 RT: (Conjugate<Canonical = T>),
458 RRStride: Stride,
459 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
460 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
461 > Add<col::generic::Col<R>> for col::generic::Col<L>
462 {
463 type Output = Col<T, Rows>;
464
465 fn add(self, rhs: _) {
466 #[track_caller]
467 fn imp<
468 T: ComplexField,
469 LT: Conjugate<Canonical = T>,
470 RT: Conjugate<Canonical = T>,
471 >(
472 lhs: ColRef<'_, LT>,
473 rhs: ColRef<'_, RT>,
474 ) -> Col<T> {
475 assert!(all(
476 lhs.nrows() == rhs.nrows(),
477 lhs.ncols() == rhs.ncols()
478 ));
479 zip!(lhs, rhs).map(add_fn::<LT, RT>())
480 }
481 let lhs = self.rb();
482 imp(
483 lhs.as_dyn_rows().as_dyn_stride(),
484 rhs.rb().as_dyn_rows().as_dyn_stride(),
485 )
486 .into_row_shape(lhs.nrows())
487 }
488 }
489 impl<
490 T: ComplexField,
491 Cols: Shape,
492 LT: (Conjugate<Canonical = T>),
493 LCStride: Stride,
494 RT: (Conjugate<Canonical = T>),
495 RCStride: Stride,
496 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
497 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
498 > Add<row::generic::Row<R>> for row::generic::Row<L>
499 {
500 type Output = Row<T, Cols>;
501
502 fn add(self, rhs: _) {
503 #[track_caller]
504 fn imp<
505 T: ComplexField,
506 LT: Conjugate<Canonical = T>,
507 RT: Conjugate<Canonical = T>,
508 >(
509 lhs: RowRef<'_, LT>,
510 rhs: RowRef<'_, RT>,
511 ) -> Row<T> {
512 assert!(all(
513 lhs.nrows() == rhs.nrows(),
514 lhs.ncols() == rhs.ncols()
515 ));
516 (lhs.transpose() + rhs.transpose()).into_transpose()
517 }
518 let lhs = self.rb();
519 imp(
520 lhs.as_dyn_cols().as_dyn_stride(),
521 rhs.rb().as_dyn_cols().as_dyn_stride(),
522 )
523 .into_col_shape(lhs.ncols())
524 }
525 }
526 impl<
527 T: ComplexField,
528 Dim: Shape,
529 LT: (Conjugate<Canonical = T>),
530 LStride: Stride,
531 RT: (Conjugate<Canonical = T>),
532 RStride: Stride,
533 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
534 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
535 > Add<diag::generic::Diag<R>> for diag::generic::Diag<L>
536 {
537 type Output = Diag<T, Dim>;
538
539 fn add(self, rhs: _) {
540 #[track_caller]
541 fn imp<
542 T: ComplexField,
543 LT: Conjugate<Canonical = T>,
544 RT: Conjugate<Canonical = T>,
545 >(
546 lhs: ColRef<'_, LT>,
547 rhs: ColRef<'_, RT>,
548 ) -> Col<T> {
549 assert!(all(lhs.nrows() == rhs.nrows()));
550 lhs + rhs
551 }
552 let lhs = self.rb();
553 imp(
554 lhs.column_vector().as_dyn_rows().as_dyn_stride(),
555 rhs.rb().column_vector().as_dyn_rows().as_dyn_stride(),
556 )
557 .into_row_shape(lhs.dim())
558 .into_diagonal()
559 }
560 }
561});
562impl_binop!({
563 impl<
564 T: ComplexField,
565 Rows: Shape,
566 Cols: Shape,
567 LT: (Conjugate<Canonical = T>),
568 LRStride: Stride,
569 LCStride: Stride,
570 RT: (Conjugate<Canonical = T>),
571 RRStride: Stride,
572 RCStride: Stride,
573 L: (for<'a> Reborrow<
574 'a,
575 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
576 >),
577 R: (for<'a> Reborrow<
578 'a,
579 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
580 >),
581 > Sub<mat::generic::Mat<R>> for mat::generic::Mat<L>
582 {
583 type Output = Mat<T, Rows, Cols>;
584
585 fn sub(self, rhs: _) {
586 #[track_caller]
587 fn imp<
588 T: ComplexField,
589 LT: Conjugate<Canonical = T>,
590 RT: Conjugate<Canonical = T>,
591 >(
592 lhs: MatRef<'_, LT>,
593 rhs: MatRef<'_, RT>,
594 ) -> Mat<T> {
595 assert!(all(
596 lhs.nrows() == rhs.nrows(),
597 lhs.ncols() == rhs.ncols()
598 ));
599 zip!(lhs, rhs).map(sub_fn::<LT, RT>())
600 }
601 let lhs = self.rb();
602 imp(
603 lhs.as_dyn().as_dyn_stride(),
604 rhs.rb().as_dyn().as_dyn_stride(),
605 )
606 .into_shape(lhs.nrows(), lhs.ncols())
607 }
608 }
609 impl<
610 T: ComplexField,
611 Rows: Shape,
612 LT: (Conjugate<Canonical = T>),
613 LRStride: Stride,
614 RT: (Conjugate<Canonical = T>),
615 RRStride: Stride,
616 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
617 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
618 > Sub<col::generic::Col<R>> for col::generic::Col<L>
619 {
620 type Output = Col<T, Rows>;
621
622 fn sub(self, rhs: _) {
623 #[track_caller]
624 fn imp<
625 T: ComplexField,
626 LT: Conjugate<Canonical = T>,
627 RT: Conjugate<Canonical = T>,
628 >(
629 lhs: ColRef<'_, LT>,
630 rhs: ColRef<'_, RT>,
631 ) -> Col<T> {
632 assert!(all(
633 lhs.nrows() == rhs.nrows(),
634 lhs.ncols() == rhs.ncols()
635 ));
636 zip!(lhs, rhs).map(sub_fn::<LT, RT>())
637 }
638 let lhs = self.rb();
639 imp(
640 lhs.as_dyn_rows().as_dyn_stride(),
641 rhs.rb().as_dyn_rows().as_dyn_stride(),
642 )
643 .into_row_shape(lhs.nrows())
644 }
645 }
646 impl<
647 T: ComplexField,
648 Cols: Shape,
649 LT: (Conjugate<Canonical = T>),
650 LCStride: Stride,
651 RT: (Conjugate<Canonical = T>),
652 RCStride: Stride,
653 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
654 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
655 > Sub<row::generic::Row<R>> for row::generic::Row<L>
656 {
657 type Output = Row<T, Cols>;
658
659 fn sub(self, rhs: _) {
660 #[track_caller]
661 fn imp<
662 T: ComplexField,
663 LT: Conjugate<Canonical = T>,
664 RT: Conjugate<Canonical = T>,
665 >(
666 lhs: RowRef<'_, LT>,
667 rhs: RowRef<'_, RT>,
668 ) -> Row<T> {
669 assert!(all(
670 lhs.nrows() == rhs.nrows(),
671 lhs.ncols() == rhs.ncols()
672 ));
673 (lhs.transpose() - rhs.transpose()).into_transpose()
674 }
675 let lhs = self.rb();
676 imp(
677 lhs.as_dyn_cols().as_dyn_stride(),
678 rhs.rb().as_dyn_cols().as_dyn_stride(),
679 )
680 .into_col_shape(lhs.ncols())
681 }
682 }
683 impl<
684 T: ComplexField,
685 Dim: Shape,
686 LT: (Conjugate<Canonical = T>),
687 LStride: Stride,
688 RT: (Conjugate<Canonical = T>),
689 RStride: Stride,
690 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
691 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
692 > Sub<diag::generic::Diag<R>> for diag::generic::Diag<L>
693 {
694 type Output = Diag<T, Dim>;
695
696 fn sub(self, rhs: _) {
697 #[track_caller]
698 fn imp<
699 T: ComplexField,
700 LT: Conjugate<Canonical = T>,
701 RT: Conjugate<Canonical = T>,
702 >(
703 lhs: ColRef<'_, LT>,
704 rhs: ColRef<'_, RT>,
705 ) -> Col<T> {
706 assert!(all(lhs.nrows() == rhs.nrows()));
707 lhs - rhs
708 }
709 let lhs = self.rb();
710 imp(
711 lhs.column_vector().as_dyn_rows().as_dyn_stride(),
712 rhs.rb().column_vector().as_dyn_rows().as_dyn_stride(),
713 )
714 .into_row_shape(lhs.dim())
715 .into_diagonal()
716 }
717 }
718});
719impl_op!({
720 impl<
721 T: Conjugate,
722 Rows: Shape,
723 Cols: Shape,
724 RStride: Stride,
725 CStride: Stride,
726 Inner: (for<'a> Reborrow<
727 'a,
728 Target = mat::Ref<'a, T, Rows, Cols, RStride, CStride>,
729 >),
730 > Neg for mat::generic::Mat<Inner>
731 {
732 type Output = Mat<T::Canonical, Rows, Cols>;
733
734 fn neg(self) {
735 #[track_caller]
736 fn imp<T: Conjugate>(A: MatRef<'_, T>) -> Mat<T::Canonical> {
737 zip!(A).map(neg_fn::<T>())
738 }
739 let A = self.rb();
740 imp(A.as_dyn().as_dyn_stride()).into_shape(A.nrows(), A.ncols())
741 }
742 }
743 impl<
744 T: Conjugate,
745 Rows: Shape,
746 RStride: Stride,
747 Inner: (for<'a> Reborrow<'a, Target = col::Ref<'a, T, Rows, RStride>>),
748 > Neg for col::generic::Col<Inner>
749 {
750 type Output = Col<T::Canonical, Rows>;
751
752 fn neg(self) {
753 #[track_caller]
754 fn imp<T: Conjugate>(A: ColRef<'_, T>) -> Col<T::Canonical> {
755 zip!(A).map(neg_fn::<T>())
756 }
757 let A = self.rb();
758 imp(A.as_dyn_rows().as_dyn_stride()).into_row_shape(A.nrows())
759 }
760 }
761 impl<
762 T: Conjugate,
763 Cols: Shape,
764 CStride: Stride,
765 Inner: (for<'a> Reborrow<'a, Target = row::Ref<'a, T, Cols, CStride>>),
766 > Neg for row::generic::Row<Inner>
767 {
768 type Output = Row<T::Canonical, Cols>;
769
770 fn neg(self) {
771 #[track_caller]
772 fn imp<T: Conjugate>(A: RowRef<'_, T>) -> Row<T::Canonical> {
773 (-A.transpose()).into_transpose()
774 }
775 let A = self.rb();
776 imp(A.as_dyn_cols().as_dyn_stride()).into_col_shape(A.ncols())
777 }
778 }
779 impl<
780 T: Conjugate,
781 Dim: Shape,
782 Stride: (crate::Stride),
783 Inner: (for<'a> Reborrow<'a, Target = diag::Ref<'a, T, Dim, Stride>>),
784 > Neg for diag::generic::Diag<Inner>
785 {
786 type Output = Diag<T::Canonical, Dim>;
787
788 fn neg(self) {
789 #[track_caller]
790 fn imp<T: Conjugate>(A: ColRef<'_, T>) -> Col<T::Canonical> {
791 -A
792 }
793 let A = self.rb().column_vector();
794 imp(A.as_dyn_rows().as_dyn_stride())
795 .into_row_shape(A.nrows())
796 .into_diagonal()
797 }
798 }
799});
800#[inline]
801fn add_fn<
802 LhsT: Conjugate<Canonical: ComplexField>,
803 RhsT: Conjugate<Canonical = LhsT::Canonical>,
804>()
805-> impl FnMut(linalg::zip::Zip<&LhsT, linalg::zip::Last<&RhsT>>) -> LhsT::Canonical
806{
807 #[inline(always)]
808 move |unzip!(a, b)| Conj::apply(a) + Conj::apply(b)
809}
810#[inline]
811fn sub_fn<
812 LhsT: Conjugate<Canonical: ComplexField>,
813 RhsT: Conjugate<Canonical = LhsT::Canonical>,
814>()
815-> impl FnMut(linalg::zip::Zip<&LhsT, linalg::zip::Last<&RhsT>>) -> LhsT::Canonical
816{
817 #[inline(always)]
818 move |unzip!(a, b)| Conj::apply(a) - Conj::apply(b)
819}
820#[inline]
821fn mul_fn<
822 LhsT: Conjugate<Canonical: ComplexField>,
823 RhsT: Conjugate<Canonical = LhsT::Canonical>,
824>()
825-> impl FnMut(linalg::zip::Zip<&LhsT, linalg::zip::Last<&RhsT>>) -> LhsT::Canonical
826{
827 #[inline(always)]
828 move |unzip!(a, b)| Conj::apply(a) * Conj::apply(b)
829}
830#[inline]
831fn neg_fn<LhsT: Conjugate<Canonical: ComplexField>>()
832-> impl FnMut(linalg::zip::Last<&LhsT>) -> LhsT::Canonical {
833 #[inline(always)]
834 move |unzip!(a)| -Conj::apply(a)
835}
836#[inline]
837fn add_assign_fn<LhsT: ComplexField, RhsT: Conjugate<Canonical = LhsT>>()
838-> impl FnMut(linalg::zip::Zip<&mut LhsT, linalg::zip::Last<&RhsT>>) {
839 #[inline(always)]
840 move |unzip!(a, b)| *a = Conj::apply(a) + Conj::apply(b)
841}
842#[inline]
843fn sub_assign_fn<LhsT: ComplexField, RhsT: Conjugate<Canonical = LhsT>>()
844-> impl FnMut(linalg::zip::Zip<&mut LhsT, linalg::zip::Last<&RhsT>>) {
845 #[inline(always)]
846 move |unzip!(a, b)| *a = Conj::apply(a) - Conj::apply(b)
847}
848mod matmul {
849 use super::*;
850 use crate::assert;
851 impl_binop!({
852 impl<
853 T: ComplexField,
854 Rows: Shape,
855 Cols: Shape,
856 Depth: Shape,
857 LT: (Conjugate<Canonical = T>),
858 LRStride: Stride,
859 LCStride: Stride,
860 RT: (Conjugate<Canonical = T>),
861 RRStride: Stride,
862 RCStride: Stride,
863 L: (for<'a> Reborrow<
864 'a,
865 Target = mat::Ref<'a, LT, Rows, Depth, LRStride, LCStride>,
866 >),
867 R: (for<'a> Reborrow<
868 'a,
869 Target = mat::Ref<'a, RT, Depth, Cols, RRStride, RCStride>,
870 >),
871 > Mul<mat::generic::Mat<R>> for mat::generic::Mat<L>
872 {
873 type Output = Mat<T, Rows, Cols>;
874
875 fn mul(self, rhs: _) {
876 #[track_caller]
877 fn imp<
878 T: ComplexField,
879 LT: Conjugate<Canonical = T>,
880 RT: Conjugate<Canonical = T>,
881 >(
882 lhs: MatRef<'_, LT>,
883 rhs: MatRef<'_, RT>,
884 ) -> Mat<T> {
885 assert!(lhs.ncols() == rhs.nrows());
886 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
887 crate::linalg::matmul::matmul(
888 out.as_mut(),
889 Accum::Replace,
890 lhs,
891 rhs,
892 T::one_impl(),
893 Par::Seq,
894 );
895 out
896 }
897 let lhs = self.rb();
898 let rhs = rhs.rb();
899 imp(lhs.as_dyn().as_dyn_stride(), rhs.as_dyn().as_dyn_stride())
900 .into_shape(lhs.nrows(), rhs.ncols())
901 }
902 }
903 impl<
904 T: ComplexField,
905 Rows: Shape,
906 Cols: Shape,
907 LT: (Conjugate<Canonical = T>),
908 LRStride: Stride,
909 LCStride: Stride,
910 RT: (Conjugate<Canonical = T>),
911 RRStride: Stride,
912 L: (for<'a> Reborrow<
913 'a,
914 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
915 >),
916 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Cols, RRStride>>),
917 > Mul<col::generic::Col<R>> for mat::generic::Mat<L>
918 {
919 type Output = Col<T, Rows>;
920
921 fn mul(self, rhs: _) {
922 #[track_caller]
923 fn imp<
924 T: ComplexField,
925 LT: Conjugate<Canonical = T>,
926 RT: Conjugate<Canonical = T>,
927 >(
928 lhs: MatRef<'_, LT>,
929 rhs: ColRef<'_, RT>,
930 ) -> Col<T> {
931 assert!(lhs.ncols() == rhs.nrows());
932 let mut out = Col::zeros(lhs.nrows());
933 crate::linalg::matmul::matmul(
934 out.as_mut(),
935 Accum::Replace,
936 lhs,
937 rhs,
938 T::one_impl(),
939 Par::Seq,
940 );
941 out
942 }
943 let lhs = self.rb();
944 let rhs = rhs.rb();
945 imp(
946 lhs.as_dyn().as_dyn_stride(),
947 rhs.as_dyn_rows().as_dyn_stride(),
948 )
949 .into_row_shape(lhs.nrows())
950 }
951 }
952 impl<
953 T: ComplexField,
954 Rows: Shape,
955 Cols: Shape,
956 LT: (Conjugate<Canonical = T>),
957 LCStride: Stride,
958 RT: (Conjugate<Canonical = T>),
959 RRStride: Stride,
960 RCStride: Stride,
961 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Rows, LCStride>>),
962 R: (for<'a> Reborrow<
963 'a,
964 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
965 >),
966 > Mul<mat::generic::Mat<R>> for row::generic::Row<L>
967 {
968 type Output = Row<T, Cols>;
969
970 fn mul(self, rhs: _) {
971 #[track_caller]
972 fn imp<
973 T: ComplexField,
974 LT: Conjugate<Canonical = T>,
975 RT: Conjugate<Canonical = T>,
976 >(
977 lhs: RowRef<'_, LT>,
978 rhs: MatRef<'_, RT>,
979 ) -> Row<T> {
980 assert!(lhs.ncols() == rhs.nrows());
981 let mut out = Row::zeros(rhs.ncols());
982 crate::linalg::matmul::matmul(
983 out.as_mut(),
984 Accum::Replace,
985 lhs,
986 rhs,
987 T::one_impl(),
988 Par::Seq,
989 );
990 out
991 }
992 let lhs = self.rb();
993 let rhs = rhs.rb();
994 imp(
995 lhs.as_dyn_cols().as_dyn_stride(),
996 rhs.as_dyn().as_dyn_stride(),
997 )
998 .into_col_shape(rhs.ncols())
999 }
1000 }
1001 impl<
1002 T: ComplexField,
1003 Dim: Shape,
1004 LT: (Conjugate<Canonical = T>),
1005 LCStride: Stride,
1006 RT: (Conjugate<Canonical = T>),
1007 RRStride: Stride,
1008 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Dim, LCStride>>),
1009 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Dim, RRStride>>),
1010 > Mul<col::generic::Col<R>> for row::generic::Row<L>
1011 {
1012 type Output = T;
1013
1014 fn mul(self, rhs: _) {
1015 #[track_caller]
1016 fn imp<
1017 T: ComplexField,
1018 LT: Conjugate<Canonical = T>,
1019 RT: Conjugate<Canonical = T>,
1020 >(
1021 lhs: RowRef<'_, LT>,
1022 rhs: ColRef<'_, RT>,
1023 ) -> T {
1024 assert!(lhs.ncols() == rhs.nrows());
1025 let mut out = [[zero::<T>()]];
1026 crate::linalg::matmul::matmul(
1027 MatMut::from_row_major_array_mut(&mut out),
1028 Accum::Replace,
1029 lhs.as_mat(),
1030 rhs.as_mat(),
1031 T::one_impl(),
1032 Par::Seq,
1033 );
1034 let [[out]] = out;
1035 out
1036 }
1037 let lhs = self.rb();
1038 let rhs = rhs.rb();
1039 imp(
1040 lhs.as_dyn_cols().as_dyn_stride(),
1041 rhs.as_dyn_rows().as_dyn_stride(),
1042 )
1043 }
1044 }
1045 impl<
1046 T: ComplexField,
1047 Rows: Shape,
1048 Cols: Shape,
1049 LT: (Conjugate<Canonical = T>),
1050 LRStride: Stride,
1051 RT: (Conjugate<Canonical = T>),
1052 RCStride: Stride,
1053 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
1054 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
1055 > Mul<row::generic::Row<R>> for col::generic::Col<L>
1056 {
1057 type Output = Mat<T, Rows, Cols>;
1058
1059 fn mul(self, rhs: _) {
1060 #[track_caller]
1061 fn imp<
1062 T: ComplexField,
1063 LT: Conjugate<Canonical = T>,
1064 RT: Conjugate<Canonical = T>,
1065 >(
1066 lhs: ColRef<'_, LT>,
1067 rhs: RowRef<'_, RT>,
1068 ) -> Mat<T> {
1069 assert!(lhs.ncols() == rhs.nrows());
1070 let mut out = Mat::zeros(lhs.nrows(), rhs.ncols());
1071 crate::linalg::matmul::matmul(
1072 out.rb_mut(),
1073 Accum::Replace,
1074 lhs,
1075 rhs,
1076 T::one_impl(),
1077 Par::Seq,
1078 );
1079 out
1080 }
1081 let lhs = self.rb();
1082 let rhs = rhs.rb();
1083 imp(
1084 lhs.as_dyn_rows().as_dyn_stride(),
1085 rhs.as_dyn_cols().as_dyn_stride(),
1086 )
1087 .into_shape(lhs.nrows(), rhs.ncols())
1088 }
1089 }
1090 impl<
1091 T: ComplexField,
1092 Dim: Shape,
1093 Cols: Shape,
1094 LT: (Conjugate<Canonical = T>),
1095 LStride: Stride,
1096 RT: (Conjugate<Canonical = T>),
1097 RRStride: Stride,
1098 RCStride: Stride,
1099 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
1100 R: (for<'a> Reborrow<
1101 'a,
1102 Target = mat::Ref<'a, RT, Dim, Cols, RRStride, RCStride>,
1103 >),
1104 > Mul<mat::generic::Mat<R>> for diag::generic::Diag<L>
1105 {
1106 type Output = Mat<T, Dim, Cols>;
1107
1108 fn mul(self, rhs: _) {
1109 #[track_caller]
1110 fn imp<
1111 T: ComplexField,
1112 LT: Conjugate<Canonical = T>,
1113 RT: Conjugate<Canonical = T>,
1114 >(
1115 lhs: ColRef<'_, LT>,
1116 rhs: MatRef<'_, RT>,
1117 ) -> Mat<T> {
1118 let lhs_dim = lhs.nrows();
1119 let rhs_nrows = rhs.nrows();
1120 assert!(lhs_dim == rhs_nrows);
1121 Mat::from_fn(rhs.nrows(), rhs.ncols(), |i, j| {
1122 Conj::apply(lhs.at(i)) * Conj::apply(rhs.at(i, j))
1123 })
1124 }
1125 let lhs = self.rb();
1126 let rhs = rhs.rb();
1127 imp(
1128 lhs.column_vector().as_dyn_rows().as_dyn_stride(),
1129 rhs.as_dyn().as_dyn_stride(),
1130 )
1131 .into_shape(rhs.nrows(), rhs.ncols())
1132 }
1133 }
1134 impl<
1135 T: ComplexField,
1136 Dim: Shape,
1137 LT: (Conjugate<Canonical = T>),
1138 LStride: Stride,
1139 RT: (Conjugate<Canonical = T>),
1140 RRStride: Stride,
1141 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
1142 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Dim, RRStride>>),
1143 > Mul<col::generic::Col<R>> for diag::generic::Diag<L>
1144 {
1145 type Output = Col<T, Dim>;
1146
1147 fn mul(self, rhs: _) {
1148 #[track_caller]
1149 fn imp<
1150 T: ComplexField,
1151 LT: Conjugate<Canonical = T>,
1152 RT: Conjugate<Canonical = T>,
1153 >(
1154 lhs: ColRef<'_, LT>,
1155 rhs: ColRef<'_, RT>,
1156 ) -> Col<T> {
1157 let lhs_dim = lhs.nrows();
1158 let rhs_nrows = rhs.nrows();
1159 assert!(lhs_dim == rhs_nrows);
1160 zip!(lhs, rhs).map(mul_fn::<LT, RT>())
1161 }
1162 let lhs = self.rb();
1163 let rhs = rhs.rb();
1164 imp(
1165 lhs.column_vector().as_dyn_rows().as_dyn_stride(),
1166 rhs.as_dyn_rows().as_dyn_stride(),
1167 )
1168 .into_row_shape(rhs.nrows())
1169 }
1170 }
1171 impl<
1172 T: ComplexField,
1173 Dim: Shape,
1174 Rows: Shape,
1175 LT: (Conjugate<Canonical = T>),
1176 LRStride: Stride,
1177 LCStride: Stride,
1178 RT: (Conjugate<Canonical = T>),
1179 RStride: Stride,
1180 L: (for<'a> Reborrow<
1181 'a,
1182 Target = mat::Ref<'a, LT, Rows, Dim, LRStride, LCStride>,
1183 >),
1184 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
1185 > Mul<diag::generic::Diag<R>> for mat::generic::Mat<L>
1186 {
1187 type Output = Mat<T, Rows, Dim>;
1188
1189 fn mul(self, rhs: _) {
1190 #[track_caller]
1191 fn imp<
1192 T: ComplexField,
1193 LT: Conjugate<Canonical = T>,
1194 RT: Conjugate<Canonical = T>,
1195 >(
1196 lhs: MatRef<'_, LT>,
1197 rhs: ColRef<'_, RT>,
1198 ) -> Mat<T> {
1199 let lhs_ncols = lhs.ncols();
1200 let rhs_dim = rhs.nrows();
1201 assert!(lhs_ncols == rhs_dim);
1202 let mut f = mul_fn::<LT, RT>();
1203 Mat::from_fn(lhs.nrows(), lhs.ncols(), |i, j| {
1204 f(linalg::zip::Zip(
1205 lhs.at(i, j),
1206 linalg::zip::Last(rhs.at(j)),
1207 ))
1208 })
1209 }
1210 let lhs = self.rb();
1211 let rhs = rhs.rb();
1212 imp(
1213 lhs.as_dyn().as_dyn_stride(),
1214 rhs.column_vector().as_dyn_rows().as_dyn_stride(),
1215 )
1216 .into_shape(lhs.nrows(), lhs.ncols())
1217 }
1218 }
1219 impl<
1220 T: ComplexField,
1221 Dim: Shape,
1222 LT: (Conjugate<Canonical = T>),
1223 LCStride: Stride,
1224 RT: (Conjugate<Canonical = T>),
1225 RStride: Stride,
1226 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Dim, LCStride>>),
1227 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
1228 > Mul<diag::generic::Diag<R>> for row::generic::Row<L>
1229 {
1230 type Output = Row<T, Dim>;
1231
1232 fn mul(self, rhs: _) {
1233 #[track_caller]
1234 fn imp<
1235 T: ComplexField,
1236 LT: Conjugate<Canonical = T>,
1237 RT: Conjugate<Canonical = T>,
1238 >(
1239 lhs: RowRef<'_, LT>,
1240 rhs: ColRef<'_, RT>,
1241 ) -> Row<T> {
1242 let lhs_ncols = lhs.ncols();
1243 let rhs_dim = rhs.nrows();
1244 assert!(lhs_ncols == rhs_dim);
1245 (rhs.as_diagonal() * lhs.transpose()).into_transpose()
1246 }
1247 let lhs = self.rb();
1248 let rhs = rhs.rb();
1249 imp(
1250 lhs.as_dyn_cols().as_dyn_stride(),
1251 rhs.column_vector().as_dyn_rows().as_dyn_stride(),
1252 )
1253 .into_col_shape(lhs.ncols())
1254 }
1255 }
1256 impl<
1257 T: ComplexField,
1258 Dim: Shape,
1259 LT: (Conjugate<Canonical = T>),
1260 LStride: Stride,
1261 RT: (Conjugate<Canonical = T>),
1262 RStride: Stride,
1263 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
1264 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
1265 > Mul<diag::generic::Diag<R>> for diag::generic::Diag<L>
1266 {
1267 type Output = Diag<T, Dim>;
1268
1269 fn mul(self, rhs: _) {
1270 #[track_caller]
1271 fn imp<
1272 T: ComplexField,
1273 LT: Conjugate<Canonical = T>,
1274 RT: Conjugate<Canonical = T>,
1275 >(
1276 lhs: ColRef<'_, LT>,
1277 rhs: ColRef<'_, RT>,
1278 ) -> Col<T> {
1279 let lhs_dim = lhs.nrows();
1280 let rhs_dim = rhs.nrows();
1281 assert!(lhs_dim == rhs_dim);
1282 lhs.as_diagonal() * rhs
1283 }
1284 let lhs = self.rb().column_vector();
1285 let rhs = rhs.rb().column_vector();
1286 imp(
1287 lhs.as_dyn_rows().as_dyn_stride(),
1288 rhs.as_dyn_rows().as_dyn_stride(),
1289 )
1290 .into_row_shape(lhs.nrows())
1291 .into_diagonal()
1292 }
1293 }
1294 });
1295}
1296impl_binop!({
1297 impl<
1298 I: Index,
1299 N: Shape,
1300 L: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, N>>),
1301 R: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, N>>),
1302 > Mul<perm::generic::Perm<R>> for perm::generic::Perm<L>
1303 {
1304 type Output = Perm<I, N>;
1305
1306 fn mul(self, rhs: _) {
1307 #[track_caller]
1308 fn imp<I: Index>(
1309 lhs: PermRef<'_, I>,
1310 rhs: PermRef<'_, I>,
1311 ) -> Perm<I> {
1312 assert!(lhs.len() == rhs.len());
1313 let truncate = <I::Signed as SignedIndex>::truncate;
1314 let mut fwd =
1315 alloc::vec![I::from_signed(truncate(0)); lhs.len()]
1316 .into_boxed_slice();
1317 let mut inv =
1318 alloc::vec![I::from_signed(truncate(0)); lhs.len()]
1319 .into_boxed_slice();
1320 for (fwd, rhs) in fwd.iter_mut().zip(rhs.arrays().0) {
1321 *fwd = lhs.arrays().0[rhs.to_signed().zx()];
1322 }
1323 for (i, fwd) in fwd.iter().enumerate() {
1324 inv[fwd.to_signed().zx()] =
1325 I::from_signed(I::Signed::truncate(i));
1326 }
1327 Perm::new_checked(fwd, inv, lhs.len())
1328 }
1329 let lhs = self.rb();
1330 let rhs = rhs.rb();
1331 let N = lhs.len();
1332 let n = N.unbound();
1333 imp(lhs.as_shape(n), rhs.as_shape(n)).into_shape(N)
1334 }
1335 }
1336 impl<
1337 I: Index,
1338 T: ComplexField,
1339 Rows: Shape,
1340 Cols: Shape,
1341 RT: (Conjugate<Canonical = T>),
1342 RRStride: Stride,
1343 RCStride: Stride,
1344 L: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Rows>>),
1345 R: (for<'a> Reborrow<
1346 'a,
1347 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
1348 >),
1349 > Mul<mat::generic::Mat<R>> for perm::generic::Perm<L>
1350 {
1351 type Output = Mat<T, Rows, Cols>;
1352
1353 fn mul(self, rhs: _) {
1354 #[track_caller]
1355 fn imp<I: Index, T: ComplexField, RT: Conjugate<Canonical = T>>(
1356 lhs: PermRef<'_, I>,
1357 rhs: MatRef<'_, RT>,
1358 ) -> Mat<T> {
1359 with_dim!(M, rhs.nrows());
1360 with_dim!(N, rhs.ncols());
1361 let rhs = rhs.as_shape(M, N);
1362 let lhs = lhs.as_shape(M);
1363 let mut out = Mat::zeros(rhs.nrows(), rhs.ncols());
1364 let fwd = lhs.bound_arrays().0;
1365 for j in rhs.ncols().indices() {
1366 for i in rhs.nrows().indices() {
1367 let fwd = fwd[i];
1368 let rhs = rhs.at(fwd.zx(), j);
1369 out[(i, j)] = Conj::apply(rhs);
1370 }
1371 }
1372 out.into_shape(*M, *N)
1373 }
1374 let lhs = self.rb();
1375 let rhs = rhs.rb();
1376 let m = rhs.nrows().unbound();
1377 imp(lhs.as_shape(m), rhs.as_dyn().as_dyn_stride())
1378 .into_shape(rhs.nrows(), rhs.ncols())
1379 }
1380 }
1381 impl<
1382 I: Index,
1383 T: ComplexField,
1384 Rows: Shape,
1385 RT: (Conjugate<Canonical = T>),
1386 RRStride: Stride,
1387 L: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Rows>>),
1388 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
1389 > Mul<col::generic::Col<R>> for perm::generic::Perm<L>
1390 {
1391 type Output = Col<T, Rows>;
1392
1393 fn mul(self, rhs: _) {
1394 #[track_caller]
1395 fn imp<I: Index, T: ComplexField, RT: Conjugate<Canonical = T>>(
1396 lhs: PermRef<'_, I>,
1397 rhs: ColRef<'_, RT>,
1398 ) -> Col<T> {
1399 with_dim!(M, rhs.nrows());
1400 let rhs = rhs.as_row_shape(M);
1401 let lhs = lhs.as_shape(M);
1402 let mut out = Col::zeros(rhs.nrows());
1403 let fwd = lhs.bound_arrays().0;
1404 for i in rhs.nrows().indices() {
1405 let fwd = fwd[i];
1406 let rhs = rhs.at(fwd.zx());
1407 out[i] = Conj::apply(rhs);
1408 }
1409 out.into_row_shape(*M)
1410 }
1411 let lhs = self.rb();
1412 let rhs = rhs.rb();
1413 let m = rhs.nrows().unbound();
1414 imp(lhs.as_shape(m), rhs.as_dyn_rows().as_dyn_stride())
1415 .into_row_shape(rhs.nrows())
1416 }
1417 }
1418 impl<
1419 I: Index,
1420 T: ComplexField,
1421 Rows: Shape,
1422 Cols: Shape,
1423 LT: (Conjugate<Canonical = T>),
1424 LRStride: Stride,
1425 LCStride: Stride,
1426 L: (for<'a> Reborrow<
1427 'a,
1428 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
1429 >),
1430 R: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Cols>>),
1431 > Mul<perm::generic::Perm<R>> for mat::generic::Mat<L>
1432 {
1433 type Output = Mat<T, Rows, Cols>;
1434
1435 fn mul(self, rhs: _) {
1436 #[track_caller]
1437 fn imp<I: Index, T: ComplexField, LT: Conjugate<Canonical = T>>(
1438 lhs: MatRef<'_, LT>,
1439 rhs: PermRef<'_, I>,
1440 ) -> Mat<T> {
1441 with_dim!(M, lhs.nrows());
1442 with_dim!(N, lhs.ncols());
1443 let lhs = lhs.as_shape(M, N);
1444 let rhs = rhs.as_shape(N);
1445 let mut out = Mat::zeros(M, N);
1446 let inv = rhs.bound_arrays().1;
1447 for j in N.indices() {
1448 let inv = inv[j];
1449 for i in M.indices() {
1450 let lhs = lhs.at(i, inv.zx());
1451 out[(i, j)] = Conj::apply(lhs);
1452 }
1453 }
1454 out.into_shape(*M, *N)
1455 }
1456 let lhs = self.rb();
1457 let rhs = rhs.rb();
1458 let n = lhs.ncols().unbound();
1459 imp(lhs.as_dyn().as_dyn_stride(), rhs.as_shape(n))
1460 .into_shape(lhs.nrows(), lhs.ncols())
1461 }
1462 }
1463 impl<
1464 I: Index,
1465 T: ComplexField,
1466 Cols: Shape,
1467 LT: (Conjugate<Canonical = T>),
1468 LCStride: Stride,
1469 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
1470 R: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Cols>>),
1471 > Mul<perm::generic::Perm<R>> for row::generic::Row<L>
1472 {
1473 type Output = Row<T, Cols>;
1474
1475 fn mul(self, rhs: _) {
1476 #[track_caller]
1477 fn imp<I: Index, T: ComplexField, LT: Conjugate<Canonical = T>>(
1478 lhs: RowRef<'_, LT>,
1479 rhs: PermRef<'_, I>,
1480 ) -> Row<T> {
1481 with_dim!(N, lhs.ncols());
1482 let lhs = lhs.as_col_shape(N);
1483 let rhs = rhs.as_shape(N);
1484 let mut out = Row::zeros(N);
1485 let inv = rhs.bound_arrays().1;
1486 for j in N.indices() {
1487 let inv = inv[j];
1488 let lhs = lhs.at(inv.zx());
1489 out[j] = Conj::apply(lhs);
1490 }
1491 out.into_col_shape(*N)
1492 }
1493 let lhs = self.rb();
1494 let rhs = rhs.rb();
1495 let n = lhs.ncols().unbound();
1496 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs.as_shape(n))
1497 .into_col_shape(lhs.ncols())
1498 }
1499 }
1500});
1501impl_binop!({
1502 impl<
1503 T: ComplexField,
1504 Rows: Shape,
1505 Cols: Shape,
1506 LT: (Conjugate<Canonical = T>),
1507 LRStride: Stride,
1508 LCStride: Stride,
1509 L: (for<'a> Reborrow<
1510 'a,
1511 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
1512 >),
1513 > Mul<Scale<T>> for mat::generic::Mat<L>
1514 {
1515 type Output = Mat<T, Rows, Cols>;
1516
1517 fn mul(self, rhs: _) {
1518 #[track_caller]
1519 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1520 lhs: MatRef<'_, LT>,
1521 rhs: &T,
1522 ) -> Mat<T> {
1523 zip!(lhs).map(|unzip!(x)| Conj::apply(x) * rhs)
1524 }
1525 let lhs = self.rb();
1526 let rhs = &rhs.0;
1527 imp(lhs.as_dyn().as_dyn_stride(), rhs)
1528 .into_shape(lhs.nrows(), lhs.ncols())
1529 }
1530 }
1531 impl<
1532 T: ComplexField,
1533 Rows: Shape,
1534 Cols: Shape,
1535 LT: (Conjugate<Canonical = T>),
1536 LRStride: Stride,
1537 LCStride: Stride,
1538 L: (for<'a> Reborrow<
1539 'a,
1540 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
1541 >),
1542 > Div<Scale<T>> for mat::generic::Mat<L>
1543 {
1544 type Output = Mat<T, Rows, Cols>;
1545
1546 fn div(self, rhs: _) {
1547 #[track_caller]
1548 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1549 lhs: MatRef<'_, LT>,
1550 rhs: &T,
1551 ) -> Mat<T> {
1552 lhs * Scale(rhs.recip())
1553 }
1554 let lhs = self.rb();
1555 let rhs = &rhs.0;
1556 imp(lhs.as_dyn().as_dyn_stride(), rhs)
1557 .into_shape(lhs.nrows(), lhs.ncols())
1558 }
1559 }
1560 impl<
1561 T: ComplexField,
1562 Rows: Shape,
1563 Cols: Shape,
1564 RT: (Conjugate<Canonical = T>),
1565 RRStride: Stride,
1566 RCStride: Stride,
1567 R: (for<'a> Reborrow<
1568 'a,
1569 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
1570 >),
1571 > Mul<mat::generic::Mat<R>> for Scale<T>
1572 {
1573 type Output = Mat<T, Rows, Cols>;
1574
1575 fn mul(self, rhs: _) {
1576 #[track_caller]
1577 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1578 lhs: &T,
1579 rhs: MatRef<'_, RT>,
1580 ) -> Mat<T> {
1581 zip!(rhs).map(|unzip!(x)| lhs * Conj::apply(x))
1582 }
1583 let lhs = &self.0;
1584 let rhs = rhs.rb();
1585 imp(lhs, rhs.as_dyn().as_dyn_stride())
1586 .into_shape(rhs.nrows(), rhs.ncols())
1587 }
1588 }
1589});
1590impl_binop!({
1591 impl<
1592 T: ComplexField,
1593 Rows: Shape,
1594 LT: (Conjugate<Canonical = T>),
1595 LRStride: Stride,
1596 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
1597 > Mul<Scale<T>> for col::generic::Col<L>
1598 {
1599 type Output = Col<T, Rows>;
1600
1601 fn mul(self, rhs: _) {
1602 #[track_caller]
1603 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1604 lhs: ColRef<'_, LT>,
1605 rhs: &T,
1606 ) -> Col<T> {
1607 zip!(lhs).map(|unzip!(x)| Conj::apply(x) * rhs)
1608 }
1609 let lhs = self.rb();
1610 let rhs = &rhs.0;
1611 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1612 .into_row_shape(lhs.nrows())
1613 }
1614 }
1615 impl<
1616 T: ComplexField,
1617 Rows: Shape,
1618 LT: (Conjugate<Canonical = T>),
1619 LRStride: Stride,
1620 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
1621 > Div<Scale<T>> for col::generic::Col<L>
1622 {
1623 type Output = Col<T, Rows>;
1624
1625 fn div(self, rhs: _) {
1626 #[track_caller]
1627 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1628 lhs: ColRef<'_, LT>,
1629 rhs: &T,
1630 ) -> Col<T> {
1631 lhs * Scale(rhs.recip())
1632 }
1633 let lhs = self.rb();
1634 let rhs = &rhs.0;
1635 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1636 .into_row_shape(lhs.nrows())
1637 }
1638 }
1639 impl<
1640 T: ComplexField,
1641 Rows: Shape,
1642 RT: (Conjugate<Canonical = T>),
1643 RRStride: Stride,
1644 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
1645 > Mul<col::generic::Col<R>> for Scale<T>
1646 {
1647 type Output = Col<T, Rows>;
1648
1649 fn mul(self, rhs: _) {
1650 #[track_caller]
1651 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1652 lhs: &T,
1653 rhs: ColRef<'_, RT>,
1654 ) -> Col<T> {
1655 zip!(rhs).map(|unzip!(x)| lhs * Conj::apply(x))
1656 }
1657 let lhs = &self.0;
1658 let rhs = rhs.rb();
1659 imp(lhs, rhs.as_dyn_rows().as_dyn_stride())
1660 .into_row_shape(rhs.nrows())
1661 }
1662 }
1663});
1664impl_binop!({
1665 impl<
1666 T: ComplexField,
1667 Cols: Shape,
1668 LT: (Conjugate<Canonical = T>),
1669 LCStride: Stride,
1670 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
1671 > Mul<Scale<T>> for row::generic::Row<L>
1672 {
1673 type Output = Row<T, Cols>;
1674
1675 fn mul(self, rhs: _) {
1676 #[track_caller]
1677 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1678 lhs: RowRef<'_, LT>,
1679 rhs: &T,
1680 ) -> Row<T> {
1681 (lhs.transpose() * Scale::from_ref(rhs)).into_transpose()
1682 }
1683 let lhs = self.rb();
1684 let rhs = &rhs.0;
1685 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs)
1686 .into_col_shape(lhs.ncols())
1687 }
1688 }
1689 impl<
1690 T: ComplexField,
1691 Cols: Shape,
1692 LT: (Conjugate<Canonical = T>),
1693 LCStride: Stride,
1694 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
1695 > Div<Scale<T>> for row::generic::Row<L>
1696 {
1697 type Output = Row<T, Cols>;
1698
1699 fn div(self, rhs: _) {
1700 #[track_caller]
1701 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1702 lhs: RowRef<'_, LT>,
1703 rhs: &T,
1704 ) -> Row<T> {
1705 lhs * Scale(rhs.recip())
1706 }
1707 let lhs = self.rb();
1708 let rhs = &rhs.0;
1709 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs)
1710 .into_col_shape(lhs.ncols())
1711 }
1712 }
1713 impl<
1714 T: ComplexField,
1715 Cols: Shape,
1716 RT: (Conjugate<Canonical = T>),
1717 RCStride: Stride,
1718 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
1719 > Mul<row::generic::Row<R>> for Scale<T>
1720 {
1721 type Output = Row<T, Cols>;
1722
1723 fn mul(self, rhs: _) {
1724 #[track_caller]
1725 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1726 lhs: &T,
1727 rhs: RowRef<'_, RT>,
1728 ) -> Row<T> {
1729 (Scale::from_ref(lhs) * rhs.transpose()).into_transpose()
1730 }
1731 let lhs = &self.0;
1732 let rhs = rhs.rb();
1733 imp(lhs, rhs.as_dyn_cols().as_dyn_stride())
1734 .into_col_shape(rhs.ncols())
1735 }
1736 }
1737});
1738impl_binop!({
1739 impl<
1740 T: ComplexField,
1741 Dim: Shape,
1742 LT: (Conjugate<Canonical = T>),
1743 LStride: Stride,
1744 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
1745 > Mul<Scale<T>> for diag::generic::Diag<L>
1746 {
1747 type Output = Diag<T, Dim>;
1748
1749 fn mul(self, rhs: _) {
1750 #[track_caller]
1751 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1752 lhs: ColRef<'_, LT>,
1753 rhs: &T,
1754 ) -> Col<T> {
1755 lhs * Scale::from_ref(rhs)
1756 }
1757 let lhs = self.rb().column_vector();
1758 let rhs = &rhs.0;
1759 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1760 .into_row_shape(lhs.nrows())
1761 .into_diagonal()
1762 }
1763 }
1764 impl<
1765 T: ComplexField,
1766 Dim: Shape,
1767 LT: (Conjugate<Canonical = T>),
1768 LStride: Stride,
1769 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
1770 > Div<Scale<T>> for diag::generic::Diag<L>
1771 {
1772 type Output = Diag<T, Dim>;
1773
1774 fn div(self, rhs: _) {
1775 #[track_caller]
1776 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1777 lhs: ColRef<'_, LT>,
1778 rhs: &T,
1779 ) -> Col<T> {
1780 lhs * Scale(rhs.recip())
1781 }
1782 let lhs = self.rb().column_vector();
1783 let rhs = &rhs.0;
1784 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1785 .into_row_shape(lhs.nrows())
1786 .into_diagonal()
1787 }
1788 }
1789 impl<
1790 T: ComplexField,
1791 Dim: Shape,
1792 RT: (Conjugate<Canonical = T>),
1793 RStride: Stride,
1794 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
1795 > Mul<diag::generic::Diag<R>> for Scale<T>
1796 {
1797 type Output = Diag<T, Dim>;
1798
1799 fn mul(self, rhs: _) {
1800 #[track_caller]
1801 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1802 lhs: &T,
1803 rhs: ColRef<'_, RT>,
1804 ) -> Col<T> {
1805 Scale::from_ref(lhs) * rhs
1806 }
1807 let lhs = &self.0;
1808 let rhs = rhs.rb().column_vector();
1809 imp(lhs, rhs.as_dyn_rows().as_dyn_stride())
1810 .into_row_shape(rhs.nrows())
1811 .into_diagonal()
1812 }
1813 }
1814});
1815impl_binop!({
1816 impl<
1817 T: ComplexField,
1818 Rows: Shape,
1819 Cols: Shape,
1820 LT: (Conjugate<Canonical = T>),
1821 LRStride: Stride,
1822 LCStride: Stride,
1823 L: (for<'a> Reborrow<
1824 'a,
1825 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
1826 >),
1827 > Mul<f64> for mat::generic::Mat<L>
1828 {
1829 type Output = Mat<T, Rows, Cols>;
1830
1831 fn mul(self, rhs: _) {
1832 #[track_caller]
1833 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1834 lhs: MatRef<'_, LT>,
1835 rhs: &T,
1836 ) -> Mat<T> {
1837 lhs * Scale::from_ref(rhs)
1838 }
1839 let lhs = self.rb();
1840 let rhs = &from_f64::<T>(*rhs);
1841 imp(lhs.as_dyn().as_dyn_stride(), rhs)
1842 .into_shape(lhs.nrows(), lhs.ncols())
1843 }
1844 }
1845 impl<
1846 T: ComplexField,
1847 Rows: Shape,
1848 Cols: Shape,
1849 LT: (Conjugate<Canonical = T>),
1850 LRStride: Stride,
1851 LCStride: Stride,
1852 L: (for<'a> Reborrow<
1853 'a,
1854 Target = mat::Ref<'a, LT, Rows, Cols, LRStride, LCStride>,
1855 >),
1856 > Div<f64> for mat::generic::Mat<L>
1857 {
1858 type Output = Mat<T, Rows, Cols>;
1859
1860 fn div(self, rhs: _) {
1861 #[track_caller]
1862 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1863 lhs: MatRef<'_, LT>,
1864 rhs: &T,
1865 ) -> Mat<T> {
1866 lhs * Scale(rhs.recip())
1867 }
1868 let lhs = self.rb();
1869 let rhs = &from_f64::<T>(*rhs);
1870 imp(lhs.as_dyn().as_dyn_stride(), rhs)
1871 .into_shape(lhs.nrows(), lhs.ncols())
1872 }
1873 }
1874 impl<
1875 T: ComplexField,
1876 Rows: Shape,
1877 Cols: Shape,
1878 RT: (Conjugate<Canonical = T>),
1879 RRStride: Stride,
1880 RCStride: Stride,
1881 R: (for<'a> Reborrow<
1882 'a,
1883 Target = mat::Ref<'a, RT, Rows, Cols, RRStride, RCStride>,
1884 >),
1885 > Mul<mat::generic::Mat<R>> for f64
1886 {
1887 type Output = Mat<T, Rows, Cols>;
1888
1889 fn mul(self, rhs: _) {
1890 #[track_caller]
1891 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1892 lhs: &T,
1893 rhs: MatRef<'_, RT>,
1894 ) -> Mat<T> {
1895 Scale::from_ref(lhs) * rhs
1896 }
1897 let lhs = &from_f64::<T>(*self);
1898 let rhs = rhs.rb();
1899 imp(lhs, rhs.as_dyn().as_dyn_stride())
1900 .into_shape(rhs.nrows(), rhs.ncols())
1901 }
1902 }
1903});
1904impl_binop!({
1905 impl<
1906 T: ComplexField,
1907 Rows: Shape,
1908 LT: (Conjugate<Canonical = T>),
1909 LRStride: Stride,
1910 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
1911 > Mul<f64> for col::generic::Col<L>
1912 {
1913 type Output = Col<T, Rows>;
1914
1915 fn mul(self, rhs: _) {
1916 #[track_caller]
1917 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1918 lhs: ColRef<'_, LT>,
1919 rhs: &T,
1920 ) -> Col<T> {
1921 lhs * Scale::from_ref(rhs)
1922 }
1923 let lhs = self.rb();
1924 let rhs = &from_f64::<T>(*rhs);
1925 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1926 .into_row_shape(lhs.nrows())
1927 }
1928 }
1929 impl<
1930 T: ComplexField,
1931 Rows: Shape,
1932 LT: (Conjugate<Canonical = T>),
1933 LRStride: Stride,
1934 L: (for<'a> Reborrow<'a, Target = col::Ref<'a, LT, Rows, LRStride>>),
1935 > Div<f64> for col::generic::Col<L>
1936 {
1937 type Output = Col<T, Rows>;
1938
1939 fn div(self, rhs: _) {
1940 #[track_caller]
1941 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1942 lhs: ColRef<'_, LT>,
1943 rhs: &T,
1944 ) -> Col<T> {
1945 lhs * Scale(rhs.recip())
1946 }
1947 let lhs = self.rb();
1948 let rhs = &from_f64::<T>(*rhs);
1949 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
1950 .into_row_shape(lhs.nrows())
1951 }
1952 }
1953 impl<
1954 T: ComplexField,
1955 Rows: Shape,
1956 RT: (Conjugate<Canonical = T>),
1957 RRStride: Stride,
1958 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Rows, RRStride>>),
1959 > Mul<col::generic::Col<R>> for f64
1960 {
1961 type Output = Col<T, Rows>;
1962
1963 fn mul(self, rhs: _) {
1964 #[track_caller]
1965 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
1966 lhs: &T,
1967 rhs: ColRef<'_, RT>,
1968 ) -> Col<T> {
1969 Scale::from_ref(lhs) * rhs
1970 }
1971 let lhs = &from_f64::<T>(*self);
1972 let rhs = rhs.rb();
1973 imp(lhs, rhs.as_dyn_rows().as_dyn_stride())
1974 .into_row_shape(rhs.nrows())
1975 }
1976 }
1977});
1978impl_binop!({
1979 impl<
1980 T: ComplexField,
1981 Cols: Shape,
1982 LT: (Conjugate<Canonical = T>),
1983 LCStride: Stride,
1984 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
1985 > Mul<f64> for row::generic::Row<L>
1986 {
1987 type Output = Row<T, Cols>;
1988
1989 fn mul(self, rhs: _) {
1990 #[track_caller]
1991 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
1992 lhs: RowRef<'_, LT>,
1993 rhs: &T,
1994 ) -> Row<T> {
1995 (lhs.transpose() * Scale::from_ref(rhs)).into_transpose()
1996 }
1997 let lhs = self.rb();
1998 let rhs = &from_f64::<T>(*rhs);
1999 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs)
2000 .into_col_shape(lhs.ncols())
2001 }
2002 }
2003 impl<
2004 T: ComplexField,
2005 Cols: Shape,
2006 LT: (Conjugate<Canonical = T>),
2007 LCStride: Stride,
2008 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Cols, LCStride>>),
2009 > Div<f64> for row::generic::Row<L>
2010 {
2011 type Output = Row<T, Cols>;
2012
2013 fn div(self, rhs: _) {
2014 #[track_caller]
2015 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
2016 lhs: RowRef<'_, LT>,
2017 rhs: &T,
2018 ) -> Row<T> {
2019 lhs * Scale(rhs.recip())
2020 }
2021 let lhs = self.rb();
2022 let rhs = &from_f64::<T>(*rhs);
2023 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs)
2024 .into_col_shape(lhs.ncols())
2025 }
2026 }
2027 impl<
2028 T: ComplexField,
2029 Cols: Shape,
2030 RT: (Conjugate<Canonical = T>),
2031 RCStride: Stride,
2032 R: (for<'a> Reborrow<'a, Target = row::Ref<'a, RT, Cols, RCStride>>),
2033 > Mul<row::generic::Row<R>> for f64
2034 {
2035 type Output = Row<T, Cols>;
2036
2037 fn mul(self, rhs: _) {
2038 #[track_caller]
2039 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
2040 lhs: &T,
2041 rhs: RowRef<'_, RT>,
2042 ) -> Row<T> {
2043 (Scale::from_ref(lhs) * rhs.transpose()).into_transpose()
2044 }
2045 let lhs = &from_f64::<T>(*self);
2046 let rhs = rhs.rb();
2047 imp(lhs, rhs.as_dyn_cols().as_dyn_stride())
2048 .into_col_shape(rhs.ncols())
2049 }
2050 }
2051});
2052impl_binop!({
2053 impl<
2054 T: ComplexField,
2055 Dim: Shape,
2056 LT: (Conjugate<Canonical = T>),
2057 LStride: Stride,
2058 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
2059 > Mul<f64> for diag::generic::Diag<L>
2060 {
2061 type Output = Diag<T, Dim>;
2062
2063 fn mul(self, rhs: _) {
2064 #[track_caller]
2065 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
2066 lhs: ColRef<'_, LT>,
2067 rhs: &T,
2068 ) -> Col<T> {
2069 lhs * Scale::from_ref(rhs)
2070 }
2071 let lhs = self.rb().column_vector();
2072 let rhs = &from_f64::<T>(*rhs);
2073 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
2074 .into_row_shape(lhs.nrows())
2075 .into_diagonal()
2076 }
2077 }
2078 impl<
2079 T: ComplexField,
2080 Dim: Shape,
2081 LT: (Conjugate<Canonical = T>),
2082 LStride: Stride,
2083 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
2084 > Div<f64> for diag::generic::Diag<L>
2085 {
2086 type Output = Diag<T, Dim>;
2087
2088 fn div(self, rhs: _) {
2089 #[track_caller]
2090 fn imp<T: ComplexField, LT: Conjugate<Canonical = T>>(
2091 lhs: ColRef<'_, LT>,
2092 rhs: &T,
2093 ) -> Col<T> {
2094 lhs * Scale(rhs.recip())
2095 }
2096 let lhs = self.rb().column_vector();
2097 let rhs = &from_f64::<T>(*rhs);
2098 imp(lhs.as_dyn_rows().as_dyn_stride(), rhs)
2099 .into_row_shape(lhs.nrows())
2100 .into_diagonal()
2101 }
2102 }
2103 impl<
2104 T: ComplexField,
2105 Dim: Shape,
2106 RT: (Conjugate<Canonical = T>),
2107 RStride: Stride,
2108 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
2109 > Mul<diag::generic::Diag<R>> for f64
2110 {
2111 type Output = Diag<T, Dim>;
2112
2113 fn mul(self, rhs: _) {
2114 #[track_caller]
2115 fn imp<T: ComplexField, RT: Conjugate<Canonical = T>>(
2116 lhs: &T,
2117 rhs: ColRef<'_, RT>,
2118 ) -> Col<T> {
2119 Scale::from_ref(lhs) * rhs
2120 }
2121 let lhs = &from_f64::<T>(*self);
2122 let rhs = rhs.rb().column_vector();
2123 imp(lhs, rhs.as_dyn_rows().as_dyn_stride())
2124 .into_row_shape(rhs.nrows())
2125 .into_diagonal()
2126 }
2127 }
2128});
2129impl_op_assign!({
2130 impl<
2131 T: ComplexField,
2132 Rows: Shape,
2133 Cols: Shape,
2134 LRStride: Stride,
2135 LCStride: Stride,
2136 L: (for<'a> ReborrowMut<
2137 'a,
2138 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
2139 >),
2140 > MulAssign<Scale<T>> for mat::generic::Mat<L>
2141 {
2142 fn mul_assign(&mut self, rhs: _) {
2143 #[track_caller]
2144 fn imp<T: ComplexField>(lhs: MatMut<'_, T>, rhs: &T) {
2145 zip!(lhs).for_each(|unzip!(x)| *x *= rhs)
2146 }
2147 let lhs = self.rb_mut();
2148 let rhs = &rhs.0;
2149 imp(lhs.as_dyn_mut().as_dyn_stride_mut(), rhs)
2150 }
2151 }
2152 impl<
2153 T: ComplexField,
2154 Rows: Shape,
2155 Cols: Shape,
2156 LRStride: Stride,
2157 LCStride: Stride,
2158 L: (for<'a> ReborrowMut<
2159 'a,
2160 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
2161 >),
2162 > DivAssign<Scale<T>> for mat::generic::Mat<L>
2163 {
2164 fn div_assign(&mut self, rhs: _) {
2165 #[track_caller]
2166 fn imp<T: ComplexField>(mut lhs: MatMut<'_, T>, rhs: &T) {
2167 lhs *= Scale(rhs.recip());
2168 }
2169 let lhs = self.rb_mut();
2170 let rhs = &rhs.0;
2171 imp(lhs.as_dyn_mut().as_dyn_stride_mut(), rhs)
2172 }
2173 }
2174});
2175impl_op_assign!({
2176 impl<
2177 T: ComplexField,
2178 Rows: Shape,
2179 LRStride: Stride,
2180 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
2181 > MulAssign<Scale<T>> for col::generic::Col<L>
2182 {
2183 fn mul_assign(&mut self, rhs: _) {
2184 #[track_caller]
2185 fn imp<T: ComplexField>(lhs: ColMut<'_, T>, rhs: &T) {
2186 zip!(lhs).for_each(|unzip!(x)| *x *= rhs)
2187 }
2188 let lhs = self.rb_mut();
2189 let rhs = &rhs.0;
2190 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2191 }
2192 }
2193 impl<
2194 T: ComplexField,
2195 Rows: Shape,
2196 LRStride: Stride,
2197 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
2198 > DivAssign<Scale<T>> for col::generic::Col<L>
2199 {
2200 fn div_assign(&mut self, rhs: _) {
2201 #[track_caller]
2202 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2203 lhs *= Scale(rhs.recip());
2204 }
2205 let lhs = self.rb_mut();
2206 let rhs = &rhs.0;
2207 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2208 }
2209 }
2210});
2211impl_op_assign!({
2212 impl<
2213 T: ComplexField,
2214 Cols: Shape,
2215 LCStride: Stride,
2216 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
2217 > MulAssign<Scale<T>> for row::generic::Row<L>
2218 {
2219 fn mul_assign(&mut self, rhs: _) {
2220 #[track_caller]
2221 fn imp<T: ComplexField>(lhs: RowMut<'_, T>, rhs: &T) {
2222 let mut lhs = lhs.transpose_mut();
2223 lhs *= Scale::from_ref(rhs);
2224 }
2225 let lhs = self.rb_mut();
2226 let rhs = &rhs.0;
2227 imp(lhs.as_dyn_cols_mut().as_dyn_stride_mut(), rhs)
2228 }
2229 }
2230 impl<
2231 T: ComplexField,
2232 Cols: Shape,
2233 LCStride: Stride,
2234 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
2235 > DivAssign<Scale<T>> for row::generic::Row<L>
2236 {
2237 fn div_assign(&mut self, rhs: _) {
2238 #[track_caller]
2239 fn imp<T: ComplexField>(mut lhs: RowMut<'_, T>, rhs: &T) {
2240 lhs *= Scale(rhs.recip());
2241 }
2242 let lhs = self.rb_mut();
2243 let rhs = &rhs.0;
2244 imp(lhs.as_dyn_cols_mut().as_dyn_stride_mut(), rhs)
2245 }
2246 }
2247});
2248impl_op_assign!({
2249 impl<
2250 T: ComplexField,
2251 Cols: Shape,
2252 LCStride: Stride,
2253 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Cols, LCStride>>),
2254 > MulAssign<Scale<T>> for diag::generic::Diag<L>
2255 {
2256 fn mul_assign(&mut self, rhs: _) {
2257 #[track_caller]
2258 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2259 lhs *= Scale::from_ref(rhs);
2260 }
2261 let lhs = self.rb_mut().column_vector_mut();
2262 let rhs = &rhs.0;
2263 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2264 }
2265 }
2266 impl<
2267 T: ComplexField,
2268 Cols: Shape,
2269 LCStride: Stride,
2270 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Cols, LCStride>>),
2271 > DivAssign<Scale<T>> for diag::generic::Diag<L>
2272 {
2273 fn div_assign(&mut self, rhs: _) {
2274 #[track_caller]
2275 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2276 lhs *= Scale(rhs.recip());
2277 }
2278 let lhs = self.rb_mut().column_vector_mut();
2279 let rhs = &rhs.0;
2280 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2281 }
2282 }
2283});
2284impl_op_assign!({
2285 impl<
2286 T: ComplexField,
2287 Rows: Shape,
2288 Cols: Shape,
2289 LRStride: Stride,
2290 LCStride: Stride,
2291 L: (for<'a> ReborrowMut<
2292 'a,
2293 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
2294 >),
2295 > MulAssign<f64> for mat::generic::Mat<L>
2296 {
2297 fn mul_assign(&mut self, rhs: _) {
2298 #[track_caller]
2299 fn imp<T: ComplexField>(lhs: MatMut<'_, T>, rhs: &T) {
2300 zip!(lhs).for_each(|unzip!(x)| *x *= rhs)
2301 }
2302 let lhs = self.rb_mut();
2303 let rhs = &from_f64::<T>(*rhs);
2304 imp(lhs.as_dyn_mut().as_dyn_stride_mut(), rhs)
2305 }
2306 }
2307 impl<
2308 T: ComplexField,
2309 Rows: Shape,
2310 Cols: Shape,
2311 LRStride: Stride,
2312 LCStride: Stride,
2313 L: (for<'a> ReborrowMut<
2314 'a,
2315 Target = mat::Mut<'a, T, Rows, Cols, LRStride, LCStride>,
2316 >),
2317 > DivAssign<f64> for mat::generic::Mat<L>
2318 {
2319 fn div_assign(&mut self, rhs: _) {
2320 #[track_caller]
2321 fn imp<T: ComplexField>(mut lhs: MatMut<'_, T>, rhs: &T) {
2322 lhs *= Scale(rhs.recip());
2323 }
2324 let lhs = self.rb_mut();
2325 let rhs = &from_f64::<T>(*rhs);
2326 imp(lhs.as_dyn_mut().as_dyn_stride_mut(), rhs)
2327 }
2328 }
2329});
2330impl_op_assign!({
2331 impl<
2332 T: ComplexField,
2333 Rows: Shape,
2334 LRStride: Stride,
2335 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
2336 > MulAssign<f64> for col::generic::Col<L>
2337 {
2338 fn mul_assign(&mut self, rhs: _) {
2339 #[track_caller]
2340 fn imp<T: ComplexField>(lhs: ColMut<'_, T>, rhs: &T) {
2341 zip!(lhs).for_each(|unzip!(x)| *x *= rhs)
2342 }
2343 let lhs = self.rb_mut();
2344 let rhs = &from_f64::<T>(*rhs);
2345 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2346 }
2347 }
2348 impl<
2349 T: ComplexField,
2350 Rows: Shape,
2351 LRStride: Stride,
2352 L: (for<'a> ReborrowMut<'a, Target = col::Mut<'a, T, Rows, LRStride>>),
2353 > DivAssign<f64> for col::generic::Col<L>
2354 {
2355 fn div_assign(&mut self, rhs: _) {
2356 #[track_caller]
2357 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2358 lhs *= Scale(rhs.recip());
2359 }
2360 let lhs = self.rb_mut();
2361 let rhs = &from_f64::<T>(*rhs);
2362 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2363 }
2364 }
2365});
2366impl_op_assign!({
2367 impl<
2368 T: ComplexField,
2369 Cols: Shape,
2370 LCStride: Stride,
2371 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
2372 > MulAssign<f64> for row::generic::Row<L>
2373 {
2374 fn mul_assign(&mut self, rhs: _) {
2375 #[track_caller]
2376 fn imp<T: ComplexField>(lhs: RowMut<'_, T>, rhs: &T) {
2377 let mut lhs = lhs.transpose_mut();
2378 lhs *= Scale::from_ref(rhs);
2379 }
2380 let lhs = self.rb_mut();
2381 let rhs = &from_f64::<T>(*rhs);
2382 imp(lhs.as_dyn_cols_mut().as_dyn_stride_mut(), rhs)
2383 }
2384 }
2385 impl<
2386 T: ComplexField,
2387 Cols: Shape,
2388 LCStride: Stride,
2389 L: (for<'a> ReborrowMut<'a, Target = row::Mut<'a, T, Cols, LCStride>>),
2390 > DivAssign<f64> for row::generic::Row<L>
2391 {
2392 fn div_assign(&mut self, rhs: _) {
2393 #[track_caller]
2394 fn imp<T: ComplexField>(mut lhs: RowMut<'_, T>, rhs: &T) {
2395 lhs *= Scale(rhs.recip());
2396 }
2397 let lhs = self.rb_mut();
2398 let rhs = &from_f64::<T>(*rhs);
2399 imp(lhs.as_dyn_cols_mut().as_dyn_stride_mut(), rhs)
2400 }
2401 }
2402});
2403impl_op_assign!({
2404 impl<
2405 T: ComplexField,
2406 Cols: Shape,
2407 LCStride: Stride,
2408 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Cols, LCStride>>),
2409 > MulAssign<f64> for diag::generic::Diag<L>
2410 {
2411 fn mul_assign(&mut self, rhs: _) {
2412 #[track_caller]
2413 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2414 lhs *= Scale::from_ref(rhs);
2415 }
2416 let lhs = self.rb_mut().column_vector_mut();
2417 let rhs = &from_f64::<T>(*rhs);
2418 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2419 }
2420 }
2421 impl<
2422 T: ComplexField,
2423 Cols: Shape,
2424 LCStride: Stride,
2425 L: (for<'a> ReborrowMut<'a, Target = diag::Mut<'a, T, Cols, LCStride>>),
2426 > DivAssign<f64> for diag::generic::Diag<L>
2427 {
2428 fn div_assign(&mut self, rhs: _) {
2429 #[track_caller]
2430 fn imp<T: ComplexField>(mut lhs: ColMut<'_, T>, rhs: &T) {
2431 lhs *= Scale(rhs.recip());
2432 }
2433 let lhs = self.rb_mut().column_vector_mut();
2434 let rhs = &from_f64::<T>(*rhs);
2435 imp(lhs.as_dyn_rows_mut().as_dyn_stride_mut(), rhs)
2436 }
2437 }
2438});
2439#[cfg(feature = "sparse")]
2440mod sparse {
2441 use super::*;
2442 use crate::internal_prelude_sp::*;
2443 use csc_numeric as csc;
2444 use csr_numeric as csr;
2445 impl_binop!({
2446 impl<
2447 I: Index,
2448 T: ComplexField,
2449 Rows: Shape,
2450 Cols: Shape,
2451 RT: (Conjugate<Canonical = T>),
2452 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
2453 > Mul<csr::generic::SparseRowMat<R>> for Scale<T>
2454 {
2455 type Output = SparseRowMat<I, T, Rows, Cols>;
2456
2457 fn mul(self, rhs: _) {
2458 #[track_caller]
2459 fn imp<
2460 I: Index,
2461 T: ComplexField,
2462 RT: Conjugate<Canonical = T>,
2463 >(
2464 lhs: &T,
2465 rhs: SparseRowMatRef<'_, I, RT>,
2466 ) -> SparseRowMat<I, T> {
2467 (Scale::from_ref(lhs) * rhs.transpose()).into_transpose()
2468 }
2469 let lhs = &self.0;
2470 let rhs = rhs.rb();
2471 imp(lhs, rhs.as_dyn()).into_shape(rhs.nrows(), rhs.ncols())
2472 }
2473 }
2474 impl<
2475 I: Index,
2476 T: ComplexField,
2477 Rows: Shape,
2478 Cols: Shape,
2479 RT: (Conjugate<Canonical = T>),
2480 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
2481 > Mul<csc::generic::SparseColMat<R>> for Scale<T>
2482 {
2483 type Output = SparseColMat<I, T, Rows, Cols>;
2484
2485 fn mul(self, rhs: _) {
2486 #[track_caller]
2487 fn imp<
2488 I: Index,
2489 T: ComplexField,
2490 RT: Conjugate<Canonical = T>,
2491 >(
2492 lhs: &T,
2493 rhs: SparseColMatRef<'_, I, RT>,
2494 ) -> SparseColMat<I, T> {
2495 with_dim!(M, rhs.nrows());
2496 with_dim!(N, rhs.ncols());
2497 let rhs = rhs.as_shape(M, N);
2498 let symbolic = rhs.symbolic().to_owned().unwrap();
2499 let mut val = alloc::vec::Vec::new();
2500 val.resize(symbolic.row_idx().len(), zero());
2501 for j in rhs.ncols().indices() {
2502 for (val, rhs) in iter::zip(
2503 &mut val[symbolic.col_range(j)],
2504 rhs.val_of_col(j),
2505 ) {
2506 *val = lhs * Conj::apply(rhs);
2507 }
2508 }
2509 SparseColMat::new(symbolic, val).into_shape(*M, *N)
2510 }
2511 let lhs = &self.0;
2512 let rhs = rhs.rb();
2513 imp(lhs, rhs.as_dyn()).into_shape(rhs.nrows(), rhs.ncols())
2514 }
2515 }
2516 });
2517 impl_binop!({
2518 impl<
2519 I: Index,
2520 T: ComplexField,
2521 Rows: Shape,
2522 Cols: Shape,
2523 LT: (Conjugate<Canonical = T>),
2524 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
2525 > Mul<Scale<T>> for csr::generic::SparseRowMat<L>
2526 {
2527 type Output = SparseRowMat<I, T, Rows, Cols>;
2528
2529 fn mul(self, rhs: _) {
2530 #[track_caller]
2531 fn imp<
2532 I: Index,
2533 T: ComplexField,
2534 LT: Conjugate<Canonical = T>,
2535 >(
2536 rhs: &T,
2537 lhs: SparseRowMatRef<'_, I, LT>,
2538 ) -> SparseRowMat<I, T> {
2539 (lhs.transpose() * Scale::from_ref(rhs)).into_transpose()
2540 }
2541 let rhs = &rhs.0;
2542 let lhs = self.rb();
2543 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2544 }
2545 }
2546 impl<
2547 I: Index,
2548 T: ComplexField,
2549 Rows: Shape,
2550 Cols: Shape,
2551 LT: (Conjugate<Canonical = T>),
2552 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
2553 > Mul<Scale<T>> for csc::generic::SparseColMat<L>
2554 {
2555 type Output = SparseColMat<I, T, Rows, Cols>;
2556
2557 fn mul(self, rhs: _) {
2558 #[track_caller]
2559 fn imp<
2560 I: Index,
2561 T: ComplexField,
2562 LT: Conjugate<Canonical = T>,
2563 >(
2564 rhs: &T,
2565 lhs: SparseColMatRef<'_, I, LT>,
2566 ) -> SparseColMat<I, T> {
2567 with_dim!(M, lhs.nrows());
2568 with_dim!(N, lhs.ncols());
2569 let lhs = lhs.as_shape(M, N);
2570 let symbolic = lhs.symbolic().to_owned().unwrap();
2571 let mut val = alloc::vec::Vec::new();
2572 val.resize(symbolic.row_idx().len(), zero());
2573 for j in lhs.ncols().indices() {
2574 for (val, lhs) in iter::zip(
2575 &mut val[symbolic.col_range(j)],
2576 lhs.val_of_col(j),
2577 ) {
2578 *val = Conj::apply(lhs) * rhs;
2579 }
2580 }
2581 SparseColMat::new(symbolic, val).into_shape(*M, *N)
2582 }
2583 let rhs = &rhs.0;
2584 let lhs = self.rb();
2585 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2586 }
2587 }
2588 impl<
2589 I: Index,
2590 T: ComplexField,
2591 Rows: Shape,
2592 Cols: Shape,
2593 LT: (Conjugate<Canonical = T>),
2594 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
2595 > Div<Scale<T>> for csr::generic::SparseRowMat<L>
2596 {
2597 type Output = SparseRowMat<I, T, Rows, Cols>;
2598
2599 fn div(self, rhs: _) {
2600 #[track_caller]
2601 fn imp<
2602 I: Index,
2603 T: ComplexField,
2604 LT: Conjugate<Canonical = T>,
2605 >(
2606 rhs: &T,
2607 lhs: SparseRowMatRef<'_, I, LT>,
2608 ) -> SparseRowMat<I, T> {
2609 lhs * Scale(rhs.recip())
2610 }
2611 let rhs = &rhs.0;
2612 let lhs = self.rb();
2613 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2614 }
2615 }
2616 impl<
2617 I: Index,
2618 T: ComplexField,
2619 Rows: Shape,
2620 Cols: Shape,
2621 LT: (Conjugate<Canonical = T>),
2622 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
2623 > Div<Scale<T>> for csc::generic::SparseColMat<L>
2624 {
2625 type Output = SparseColMat<I, T, Rows, Cols>;
2626
2627 fn div(self, rhs: _) {
2628 #[track_caller]
2629 fn imp<
2630 I: Index,
2631 T: ComplexField,
2632 LT: Conjugate<Canonical = T>,
2633 >(
2634 rhs: &T,
2635 lhs: SparseColMatRef<'_, I, LT>,
2636 ) -> SparseColMat<I, T> {
2637 lhs * Scale(rhs.recip())
2638 }
2639 let rhs = &rhs.0;
2640 let lhs = self.rb();
2641 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2642 }
2643 }
2644 });
2645 impl_op_assign!({
2646 impl<
2647 I: Index,
2648 T: ComplexField,
2649 Rows: Shape,
2650 Cols: Shape,
2651 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
2652 > MulAssign<Scale<T>> for csr::generic::SparseRowMat<L>
2653 {
2654 fn mul_assign(&mut self, rhs: _) {
2655 #[track_caller]
2656 fn imp<I: Index, T: ComplexField>(
2657 rhs: &T,
2658 lhs: SparseRowMatMut<'_, I, T>,
2659 ) {
2660 let mut lhs = lhs.transpose_mut();
2661 lhs *= Scale::from_ref(rhs);
2662 }
2663 let rhs = &rhs.0;
2664 let lhs = self.rb_mut();
2665 imp(rhs, lhs.as_dyn_mut())
2666 }
2667 }
2668 impl<
2669 I: Index,
2670 T: ComplexField,
2671 Rows: Shape,
2672 Cols: Shape,
2673 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
2674 > MulAssign<Scale<T>> for csc::generic::SparseColMat<L>
2675 {
2676 fn mul_assign(&mut self, rhs: _) {
2677 #[track_caller]
2678 fn imp<I: Index, T: ComplexField>(
2679 rhs: &T,
2680 lhs: SparseColMatMut<'_, I, T>,
2681 ) {
2682 with_dim!(M, lhs.nrows());
2683 with_dim!(N, lhs.ncols());
2684 let mut lhs = lhs.as_shape_mut(M, N);
2685 for j in lhs.ncols().indices() {
2686 for val in lhs.rb_mut().val_of_col_mut(j) {
2687 *val *= rhs;
2688 }
2689 }
2690 }
2691 let rhs = &rhs.0;
2692 let lhs = self.rb_mut();
2693 imp(rhs, lhs.as_dyn_mut())
2694 }
2695 }
2696 impl<
2697 I: Index,
2698 T: ComplexField,
2699 Rows: Shape,
2700 Cols: Shape,
2701 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
2702 > DivAssign<Scale<T>> for csr::generic::SparseRowMat<L>
2703 {
2704 fn div_assign(&mut self, rhs: _) {
2705 #[track_caller]
2706 fn imp<I: Index, T: ComplexField>(
2707 rhs: &T,
2708 lhs: SparseRowMatMut<'_, I, T>,
2709 ) {
2710 let mut lhs = lhs.transpose_mut();
2711 lhs /= Scale::from_ref(rhs);
2712 }
2713 let rhs = &rhs.0;
2714 let lhs = self.rb_mut();
2715 imp(rhs, lhs.as_dyn_mut())
2716 }
2717 }
2718 impl<
2719 I: Index,
2720 T: ComplexField,
2721 Rows: Shape,
2722 Cols: Shape,
2723 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
2724 > DivAssign<Scale<T>> for csc::generic::SparseColMat<L>
2725 {
2726 fn div_assign(&mut self, rhs: _) {
2727 #[track_caller]
2728 fn imp<I: Index, T: ComplexField>(
2729 rhs: &T,
2730 lhs: SparseColMatMut<'_, I, T>,
2731 ) {
2732 let mut lhs = lhs.transpose_mut();
2733 lhs *= Scale(rhs.recip());
2734 }
2735 let rhs = &rhs.0;
2736 let lhs = self.rb_mut();
2737 imp(rhs, lhs.as_dyn_mut())
2738 }
2739 }
2740 });
2741 impl_binop!({
2742 impl<
2743 I: Index,
2744 T: ComplexField,
2745 Rows: Shape,
2746 Cols: Shape,
2747 RT: (Conjugate<Canonical = T>),
2748 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
2749 > Mul<csr::generic::SparseRowMat<R>> for f64
2750 {
2751 type Output = SparseRowMat<I, T, Rows, Cols>;
2752
2753 fn mul(self, rhs: _) {
2754 #[track_caller]
2755 fn imp<
2756 I: Index,
2757 T: ComplexField,
2758 RT: Conjugate<Canonical = T>,
2759 >(
2760 lhs: &T,
2761 rhs: SparseRowMatRef<'_, I, RT>,
2762 ) -> SparseRowMat<I, T> {
2763 (Scale::from_ref(lhs) * rhs.transpose()).into_transpose()
2764 }
2765 let lhs = &from_f64::<T>(*self);
2766 let rhs = rhs.rb();
2767 imp(lhs, rhs.as_dyn()).into_shape(rhs.nrows(), rhs.ncols())
2768 }
2769 }
2770 impl<
2771 I: Index,
2772 T: ComplexField,
2773 Rows: Shape,
2774 Cols: Shape,
2775 RT: (Conjugate<Canonical = T>),
2776 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
2777 > Mul<csc::generic::SparseColMat<R>> for f64
2778 {
2779 type Output = SparseColMat<I, T, Rows, Cols>;
2780
2781 fn mul(self, rhs: _) {
2782 #[track_caller]
2783 fn imp<
2784 I: Index,
2785 T: ComplexField,
2786 RT: Conjugate<Canonical = T>,
2787 >(
2788 lhs: &T,
2789 rhs: SparseColMatRef<'_, I, RT>,
2790 ) -> SparseColMat<I, T> {
2791 Scale::from_ref(lhs) * rhs
2792 }
2793 let lhs = &from_f64::<T>(*self);
2794 let rhs = rhs.rb();
2795 imp(lhs, rhs.as_dyn()).into_shape(rhs.nrows(), rhs.ncols())
2796 }
2797 }
2798 });
2799 impl_binop!({
2800 impl<
2801 I: Index,
2802 T: ComplexField,
2803 Rows: Shape,
2804 Cols: Shape,
2805 LT: (Conjugate<Canonical = T>),
2806 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
2807 > Mul<f64> for csr::generic::SparseRowMat<L>
2808 {
2809 type Output = SparseRowMat<I, T, Rows, Cols>;
2810
2811 fn mul(self, rhs: _) {
2812 #[track_caller]
2813 fn imp<
2814 I: Index,
2815 T: ComplexField,
2816 LT: Conjugate<Canonical = T>,
2817 >(
2818 rhs: &T,
2819 lhs: SparseRowMatRef<'_, I, LT>,
2820 ) -> SparseRowMat<I, T> {
2821 (lhs.transpose() * Scale::from_ref(rhs)).into_transpose()
2822 }
2823 let rhs = &from_f64::<T>(*rhs);
2824 let lhs = self.rb();
2825 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2826 }
2827 }
2828 impl<
2829 I: Index,
2830 T: ComplexField,
2831 Rows: Shape,
2832 Cols: Shape,
2833 LT: (Conjugate<Canonical = T>),
2834 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
2835 > Mul<f64> for csc::generic::SparseColMat<L>
2836 {
2837 type Output = SparseColMat<I, T, Rows, Cols>;
2838
2839 fn mul(self, rhs: _) {
2840 #[track_caller]
2841 fn imp<
2842 I: Index,
2843 T: ComplexField,
2844 LT: Conjugate<Canonical = T>,
2845 >(
2846 rhs: &T,
2847 lhs: SparseColMatRef<'_, I, LT>,
2848 ) -> SparseColMat<I, T> {
2849 lhs * Scale::from_ref(rhs)
2850 }
2851 let rhs = &from_f64::<T>(*rhs);
2852 let lhs = self.rb();
2853 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2854 }
2855 }
2856 impl<
2857 I: Index,
2858 T: ComplexField,
2859 Rows: Shape,
2860 Cols: Shape,
2861 LT: (Conjugate<Canonical = T>),
2862 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
2863 > Div<f64> for csr::generic::SparseRowMat<L>
2864 {
2865 type Output = SparseRowMat<I, T, Rows, Cols>;
2866
2867 fn div(self, rhs: _) {
2868 #[track_caller]
2869 fn imp<
2870 I: Index,
2871 T: ComplexField,
2872 LT: Conjugate<Canonical = T>,
2873 >(
2874 rhs: &T,
2875 lhs: SparseRowMatRef<'_, I, LT>,
2876 ) -> SparseRowMat<I, T> {
2877 lhs * Scale(rhs.recip())
2878 }
2879 let rhs = &from_f64::<T>(*rhs);
2880 let lhs = self.rb();
2881 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2882 }
2883 }
2884 impl<
2885 I: Index,
2886 T: ComplexField,
2887 Rows: Shape,
2888 Cols: Shape,
2889 LT: (Conjugate<Canonical = T>),
2890 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
2891 > Div<f64> for csc::generic::SparseColMat<L>
2892 {
2893 type Output = SparseColMat<I, T, Rows, Cols>;
2894
2895 fn div(self, rhs: _) {
2896 #[track_caller]
2897 fn imp<
2898 I: Index,
2899 T: ComplexField,
2900 LT: Conjugate<Canonical = T>,
2901 >(
2902 rhs: &T,
2903 lhs: SparseColMatRef<'_, I, LT>,
2904 ) -> SparseColMat<I, T> {
2905 lhs * Scale(rhs.recip())
2906 }
2907 let rhs = &from_f64::<T>(*rhs);
2908 let lhs = self.rb();
2909 imp(rhs, lhs.as_dyn()).into_shape(lhs.nrows(), lhs.ncols())
2910 }
2911 }
2912 });
2913 impl_op_assign!({
2914 impl<
2915 I: Index,
2916 T: ComplexField,
2917 Rows: Shape,
2918 Cols: Shape,
2919 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
2920 > MulAssign<f64> for csr::generic::SparseRowMat<L>
2921 {
2922 fn mul_assign(&mut self, rhs: _) {
2923 #[track_caller]
2924 fn imp<I: Index, T: ComplexField>(
2925 rhs: &T,
2926 lhs: SparseRowMatMut<'_, I, T>,
2927 ) {
2928 let mut lhs = lhs.transpose_mut();
2929 lhs *= Scale::from_ref(rhs);
2930 }
2931 let rhs = &from_f64::<T>(*rhs);
2932 let lhs = self.rb_mut();
2933 imp(rhs, lhs.as_dyn_mut())
2934 }
2935 }
2936 impl<
2937 I: Index,
2938 T: ComplexField,
2939 Rows: Shape,
2940 Cols: Shape,
2941 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
2942 > MulAssign<f64> for csc::generic::SparseColMat<L>
2943 {
2944 fn mul_assign(&mut self, rhs: _) {
2945 #[track_caller]
2946 fn imp<I: Index, T: ComplexField>(
2947 rhs: &T,
2948 lhs: SparseColMatMut<'_, I, T>,
2949 ) {
2950 *&mut { lhs } *= Scale::from_ref(rhs)
2951 }
2952 let rhs = &from_f64::<T>(*rhs);
2953 let lhs = self.rb_mut();
2954 imp(rhs, lhs.as_dyn_mut())
2955 }
2956 }
2957 impl<
2958 I: Index,
2959 T: ComplexField,
2960 Rows: Shape,
2961 Cols: Shape,
2962 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
2963 > DivAssign<f64> for csr::generic::SparseRowMat<L>
2964 {
2965 fn div_assign(&mut self, rhs: _) {
2966 #[track_caller]
2967 fn imp<I: Index, T: ComplexField>(
2968 rhs: &T,
2969 lhs: SparseRowMatMut<'_, I, T>,
2970 ) {
2971 let mut lhs = lhs.transpose_mut();
2972 lhs /= Scale::from_ref(rhs);
2973 }
2974 let rhs = &from_f64::<T>(*rhs);
2975 let lhs = self.rb_mut();
2976 imp(rhs, lhs.as_dyn_mut())
2977 }
2978 }
2979 impl<
2980 I: Index,
2981 T: ComplexField,
2982 Rows: Shape,
2983 Cols: Shape,
2984 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
2985 > DivAssign<f64> for csc::generic::SparseColMat<L>
2986 {
2987 fn div_assign(&mut self, rhs: _) {
2988 #[track_caller]
2989 fn imp<I: Index, T: ComplexField>(
2990 rhs: &T,
2991 lhs: SparseColMatMut<'_, I, T>,
2992 ) {
2993 let mut lhs = lhs.transpose_mut();
2994 lhs *= Scale(rhs.recip());
2995 }
2996 let rhs = &from_f64::<T>(*rhs);
2997 let lhs = self.rb_mut();
2998 imp(rhs, lhs.as_dyn_mut())
2999 }
3000 }
3001 });
3002 impl_op!({
3003 impl<
3004 I: Index,
3005 T: Conjugate,
3006 Rows: Shape,
3007 Cols: Shape,
3008 Inner: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, T, Rows, Cols>>),
3009 > Neg for csr::generic::SparseRowMat<Inner>
3010 {
3011 type Output = SparseRowMat<I, T::Canonical, Rows, Cols>;
3012
3013 fn neg(self) {
3014 self.rb().transpose().neg().into_transpose()
3015 }
3016 }
3017 impl<
3018 I: Index,
3019 T: Conjugate,
3020 Rows: Shape,
3021 Cols: Shape,
3022 Inner: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, T, Rows, Cols>>),
3023 > Neg for csc::generic::SparseColMat<Inner>
3024 {
3025 type Output = SparseColMat<I, T::Canonical, Rows, Cols>;
3026
3027 fn neg(self) {
3028 #[track_caller]
3029 fn imp<I: Index, T: Conjugate>(
3030 A: SparseColMatRef<'_, I, T>,
3031 ) -> SparseColMat<I, T::Canonical> {
3032 with_dim!(M, A.nrows());
3033 with_dim!(N, A.ncols());
3034 let A = A.as_shape(M, N);
3035 let symbolic = A.symbolic().to_owned().unwrap();
3036 let mut val = alloc::vec::Vec::new();
3037 val.resize(symbolic.row_idx().len(), zero());
3038 for j in A.ncols().indices() {
3039 for (val, lhs) in iter::zip(
3040 &mut val[symbolic.col_range(j)],
3041 A.val_of_col(j),
3042 ) {
3043 *val = -Conj::apply(lhs);
3044 }
3045 }
3046 SparseColMat::new(symbolic, val).into_shape(*M, *N)
3047 }
3048 let A = self.rb();
3049 imp(A.as_dyn()).into_shape(A.nrows(), A.ncols())
3050 }
3051 }
3052 });
3053 impl_op_assign!({
3054 impl<
3055 I: Index,
3056 T: ComplexField,
3057 Rows: Shape,
3058 Cols: Shape,
3059 RT: (Conjugate<Canonical = T>),
3060 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
3061 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
3062 > AddAssign<csc::generic::SparseColMat<R>> for csc::generic::SparseColMat<L>
3063 {
3064 fn add_assign(&mut self, rhs: _) {
3065 #[track_caller]
3066 fn imp<
3067 I: Index,
3068 T: ComplexField,
3069 RT: Conjugate<Canonical = T>,
3070 >(
3071 lhs: SparseColMatMut<'_, I, T>,
3072 rhs: SparseColMatRef<'_, I, RT>,
3073 ) {
3074 crate::sparse::ops::binary_op_assign_into(
3075 lhs,
3076 rhs,
3077 add_assign_fn::<T, RT>,
3078 )
3079 }
3080 let lhs = self.rb_mut();
3081 let rhs = rhs.rb();
3082 imp(lhs.as_dyn_mut(), rhs.as_dyn())
3083 }
3084 }
3085 impl<
3086 I: Index,
3087 T: ComplexField,
3088 Rows: Shape,
3089 Cols: Shape,
3090 RT: (Conjugate<Canonical = T>),
3091 L: (for<'a> ReborrowMut<'a, Target = csc::Mut<'a, I, T, Rows, Cols>>),
3092 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
3093 > SubAssign<csc::generic::SparseColMat<R>> for csc::generic::SparseColMat<L>
3094 {
3095 fn sub_assign(&mut self, rhs: _) {
3096 #[track_caller]
3097 fn imp<
3098 I: Index,
3099 T: ComplexField,
3100 RT: Conjugate<Canonical = T>,
3101 >(
3102 lhs: SparseColMatMut<'_, I, T>,
3103 rhs: SparseColMatRef<'_, I, RT>,
3104 ) {
3105 crate::sparse::ops::binary_op_assign_into(
3106 lhs,
3107 rhs,
3108 sub_assign_fn::<T, RT>,
3109 )
3110 }
3111 let lhs = self.rb_mut();
3112 let rhs = rhs.rb();
3113 imp(lhs.as_dyn_mut(), rhs.as_dyn())
3114 }
3115 }
3116 });
3117 impl_op_assign!({
3118 impl<
3119 I: Index,
3120 T: ComplexField,
3121 Rows: Shape,
3122 Cols: Shape,
3123 RT: (Conjugate<Canonical = T>),
3124 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
3125 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
3126 > AddAssign<csr::generic::SparseRowMat<R>> for csr::generic::SparseRowMat<L>
3127 {
3128 fn add_assign(&mut self, rhs: _) {
3129 #[track_caller]
3130 fn imp<
3131 I: Index,
3132 T: ComplexField,
3133 RT: Conjugate<Canonical = T>,
3134 >(
3135 lhs: SparseRowMatMut<'_, I, T>,
3136 rhs: SparseRowMatRef<'_, I, RT>,
3137 ) {
3138 crate::sparse::ops::binary_op_assign_into(
3139 lhs.transpose_mut(),
3140 rhs.transpose(),
3141 add_assign_fn::<T, RT>,
3142 )
3143 }
3144 let lhs = self.rb_mut();
3145 let rhs = rhs.rb();
3146 imp(lhs.as_dyn_mut(), rhs.as_dyn())
3147 }
3148 }
3149 impl<
3150 I: Index,
3151 T: ComplexField,
3152 Rows: Shape,
3153 Cols: Shape,
3154 RT: (Conjugate<Canonical = T>),
3155 L: (for<'a> ReborrowMut<'a, Target = csr::Mut<'a, I, T, Rows, Cols>>),
3156 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
3157 > SubAssign<csr::generic::SparseRowMat<R>> for csr::generic::SparseRowMat<L>
3158 {
3159 fn sub_assign(&mut self, rhs: _) {
3160 #[track_caller]
3161 fn imp<
3162 I: Index,
3163 T: ComplexField,
3164 RT: Conjugate<Canonical = T>,
3165 >(
3166 lhs: SparseRowMatMut<'_, I, T>,
3167 rhs: SparseRowMatRef<'_, I, RT>,
3168 ) {
3169 crate::sparse::ops::binary_op_assign_into(
3170 lhs.transpose_mut(),
3171 rhs.transpose(),
3172 sub_assign_fn::<T, RT>,
3173 )
3174 }
3175 let lhs = self.rb_mut();
3176 let rhs = rhs.rb();
3177 imp(lhs.as_dyn_mut(), rhs.as_dyn())
3178 }
3179 }
3180 });
3181 impl_binop!({
3182 impl<
3183 I: Index,
3184 T: ComplexField,
3185 Rows: Shape,
3186 Cols: Shape,
3187 LT: (Conjugate<Canonical = T>),
3188 RT: (Conjugate<Canonical = T>),
3189 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
3190 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
3191 > Add<csc::generic::SparseColMat<R>> for csc::generic::SparseColMat<L>
3192 {
3193 type Output = SparseColMat<I, T, Rows, Cols>;
3194
3195 fn add(self, rhs: _) {
3196 #[track_caller]
3197 fn imp<
3198 I: Index,
3199 T: ComplexField,
3200 LT: Conjugate<Canonical = T>,
3201 RT: Conjugate<Canonical = T>,
3202 >(
3203 lhs: SparseColMatRef<'_, I, LT>,
3204 rhs: SparseColMatRef<'_, I, RT>,
3205 ) -> SparseColMat<I, T> {
3206 crate::sparse::ops::binary_op(lhs, rhs, add_fn::<T, LT, RT>)
3207 .unwrap()
3208 }
3209 let lhs = self.rb();
3210 let rhs = rhs.rb();
3211 let (nrows, ncols) = lhs.shape();
3212 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3213 }
3214 }
3215 impl<
3216 I: Index,
3217 T: ComplexField,
3218 Rows: Shape,
3219 Cols: Shape,
3220 LT: (Conjugate<Canonical = T>),
3221 RT: (Conjugate<Canonical = T>),
3222 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Cols>>),
3223 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Rows, Cols>>),
3224 > Sub<csc::generic::SparseColMat<R>> for csc::generic::SparseColMat<L>
3225 {
3226 type Output = SparseColMat<I, T, Rows, Cols>;
3227
3228 fn sub(self, rhs: _) {
3229 #[track_caller]
3230 fn imp<
3231 I: Index,
3232 T: ComplexField,
3233 LT: Conjugate<Canonical = T>,
3234 RT: Conjugate<Canonical = T>,
3235 >(
3236 lhs: SparseColMatRef<'_, I, LT>,
3237 rhs: SparseColMatRef<'_, I, RT>,
3238 ) -> SparseColMat<I, T> {
3239 crate::sparse::ops::binary_op(lhs, rhs, sub_fn::<T, LT, RT>)
3240 .unwrap()
3241 }
3242 let lhs = self.rb();
3243 let rhs = rhs.rb();
3244 let (nrows, ncols) = lhs.shape();
3245 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3246 }
3247 }
3248 });
3249 impl_binop!({
3250 impl<
3251 I: Index,
3252 T: ComplexField,
3253 Rows: Shape,
3254 Cols: Shape,
3255 LT: (Conjugate<Canonical = T>),
3256 RT: (Conjugate<Canonical = T>),
3257 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
3258 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
3259 > Add<csr::generic::SparseRowMat<R>> for csr::generic::SparseRowMat<L>
3260 {
3261 type Output = SparseRowMat<I, T, Rows, Cols>;
3262
3263 fn add(self, rhs: _) {
3264 #[track_caller]
3265 fn imp<
3266 I: Index,
3267 T: ComplexField,
3268 LT: Conjugate<Canonical = T>,
3269 RT: Conjugate<Canonical = T>,
3270 >(
3271 lhs: SparseRowMatRef<'_, I, LT>,
3272 rhs: SparseRowMatRef<'_, I, RT>,
3273 ) -> SparseRowMat<I, T> {
3274 crate::sparse::ops::binary_op(
3275 lhs.transpose(),
3276 rhs.transpose(),
3277 add_fn::<T, LT, RT>,
3278 )
3279 .unwrap()
3280 .into_transpose()
3281 }
3282 let lhs = self.rb();
3283 let rhs = rhs.rb();
3284 let (nrows, ncols) = lhs.shape();
3285 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3286 }
3287 }
3288 impl<
3289 I: Index,
3290 T: ComplexField,
3291 Rows: Shape,
3292 Cols: Shape,
3293 LT: (Conjugate<Canonical = T>),
3294 RT: (Conjugate<Canonical = T>),
3295 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Cols>>),
3296 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Rows, Cols>>),
3297 > Sub<csr::generic::SparseRowMat<R>> for csr::generic::SparseRowMat<L>
3298 {
3299 type Output = SparseRowMat<I, T, Rows, Cols>;
3300
3301 fn sub(self, rhs: _) {
3302 #[track_caller]
3303 fn imp<
3304 I: Index,
3305 T: ComplexField,
3306 LT: Conjugate<Canonical = T>,
3307 RT: Conjugate<Canonical = T>,
3308 >(
3309 lhs: SparseRowMatRef<'_, I, LT>,
3310 rhs: SparseRowMatRef<'_, I, RT>,
3311 ) -> SparseRowMat<I, T> {
3312 crate::sparse::ops::binary_op(
3313 lhs.transpose(),
3314 rhs.transpose(),
3315 sub_fn::<T, LT, RT>,
3316 )
3317 .unwrap()
3318 .into_transpose()
3319 }
3320 let lhs = self.rb();
3321 let rhs = rhs.rb();
3322 let (nrows, ncols) = lhs.shape();
3323 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3324 }
3325 }
3326 });
3327 impl_binop!({
3328 impl<
3329 I: Index,
3330 T: ComplexField,
3331 Rows: Shape,
3332 Cols: Shape,
3333 Depth: Shape,
3334 LT: (Conjugate<Canonical = T>),
3335 RT: (Conjugate<Canonical = T>),
3336 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Depth>>),
3337 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Depth, Cols>>),
3338 > Mul<csc::generic::SparseColMat<R>> for csc::generic::SparseColMat<L>
3339 {
3340 type Output = SparseColMat<I, T, Rows, Cols>;
3341
3342 fn mul(self, rhs: _) {
3343 #[track_caller]
3344 fn imp<
3345 I: Index,
3346 T: ComplexField,
3347 LT: Conjugate<Canonical = T>,
3348 RT: Conjugate<Canonical = T>,
3349 >(
3350 lhs: SparseColMatRef<'_, I, LT>,
3351 rhs: SparseColMatRef<'_, I, RT>,
3352 ) -> SparseColMat<I, T> {
3353 let nrows = lhs.nrows();
3354 let ncols = rhs.ncols();
3355 linalg_sp::matmul::sparse_sparse_matmul(
3356 lhs,
3357 rhs,
3358 one::<T>(),
3359 crate::Par::Seq,
3360 )
3361 .unwrap()
3362 .into_shape(nrows, ncols)
3363 }
3364 let lhs = self.rb();
3365 let rhs = rhs.rb();
3366 let nrows = lhs.nrows();
3367 let ncols = rhs.ncols();
3368 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3369 }
3370 }
3371 impl<
3372 I: Index,
3373 T: ComplexField,
3374 Rows: Shape,
3375 Cols: Shape,
3376 Depth: Shape,
3377 LT: (Conjugate<Canonical = T>),
3378 RT: (Conjugate<Canonical = T>),
3379 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Depth>>),
3380 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Depth, Cols>>),
3381 > Mul<csr::generic::SparseRowMat<R>> for csr::generic::SparseRowMat<L>
3382 {
3383 type Output = SparseRowMat<I, T, Rows, Cols>;
3384
3385 fn mul(self, rhs: _) {
3386 #[track_caller]
3387 fn imp<
3388 I: Index,
3389 T: ComplexField,
3390 LT: Conjugate<Canonical = T>,
3391 RT: Conjugate<Canonical = T>,
3392 >(
3393 lhs: SparseRowMatRef<'_, I, LT>,
3394 rhs: SparseRowMatRef<'_, I, RT>,
3395 ) -> SparseRowMat<I, T> {
3396 (rhs.transpose() * lhs.transpose()).into_transpose()
3397 }
3398 let lhs = self.rb();
3399 let rhs = rhs.rb();
3400 let nrows = lhs.nrows();
3401 let ncols = rhs.ncols();
3402 imp(lhs.as_dyn(), rhs.as_dyn()).into_shape(nrows, ncols)
3403 }
3404 }
3405 });
3406 impl_binop!({
3407 impl<
3408 I: Index,
3409 T: ComplexField,
3410 Rows: Shape,
3411 Cols: Shape,
3412 Depth: Shape,
3413 LT: (Conjugate<Canonical = T>),
3414 RT: (Conjugate<Canonical = T>),
3415 RRStride: Stride,
3416 RCStride: Stride,
3417 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Depth>>),
3418 R: (for<'a> Reborrow<
3419 'a,
3420 Target = mat::Ref<'a, RT, Depth, Cols, RRStride, RCStride>,
3421 >),
3422 > Mul<mat::generic::Mat<R>> for csc::generic::SparseColMat<L>
3423 {
3424 type Output = Mat<T, Rows, Cols>;
3425
3426 fn mul(self, rhs: _) {
3427 #[track_caller]
3428 fn imp<
3429 I: Index,
3430 T: ComplexField,
3431 LT: Conjugate<Canonical = T>,
3432 RT: Conjugate<Canonical = T>,
3433 >(
3434 lhs: SparseColMatRef<'_, I, LT>,
3435 rhs: MatRef<'_, RT>,
3436 ) -> Mat<T> {
3437 let nrows = lhs.nrows();
3438 let ncols = rhs.ncols();
3439 let mut out = Mat::zeros(nrows, ncols);
3440 linalg_sp::matmul::sparse_dense_matmul(
3441 out.rb_mut(),
3442 Accum::Add,
3443 lhs,
3444 rhs,
3445 T::one_impl(),
3446 crate::Par::Seq,
3447 );
3448 out
3449 }
3450 let lhs = self.rb();
3451 let rhs = rhs.rb();
3452 let nrows = lhs.nrows();
3453 let ncols = rhs.ncols();
3454 imp(lhs.as_dyn(), rhs.as_dyn().as_dyn_stride())
3455 .into_shape(nrows, ncols)
3456 }
3457 }
3458 impl<
3459 I: Index,
3460 T: ComplexField,
3461 Rows: Shape,
3462 Cols: Shape,
3463 Depth: Shape,
3464 LT: (Conjugate<Canonical = T>),
3465 RT: (Conjugate<Canonical = T>),
3466 RRStride: Stride,
3467 RCStride: Stride,
3468 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Depth>>),
3469 R: (for<'a> Reborrow<
3470 'a,
3471 Target = mat::Ref<'a, RT, Depth, Cols, RRStride, RCStride>,
3472 >),
3473 > Mul<mat::generic::Mat<R>> for csr::generic::SparseRowMat<L>
3474 {
3475 type Output = Mat<T, Rows, Cols>;
3476
3477 fn mul(self, rhs: _) {
3478 #[track_caller]
3479 fn imp<
3480 I: Index,
3481 T: ComplexField,
3482 LT: Conjugate<Canonical = T>,
3483 RT: Conjugate<Canonical = T>,
3484 >(
3485 lhs: SparseRowMatRef<'_, I, LT>,
3486 rhs: MatRef<'_, RT>,
3487 ) -> Mat<T> {
3488 let nrows = lhs.nrows();
3489 let ncols = rhs.ncols();
3490 let mut out = Mat::zeros(nrows, ncols);
3491 linalg_sp::matmul::dense_sparse_matmul(
3492 out.rb_mut().transpose_mut(),
3493 Accum::Add,
3494 rhs.transpose(),
3495 lhs.transpose(),
3496 T::one_impl(),
3497 crate::Par::Seq,
3498 );
3499 out
3500 }
3501 let lhs = self.rb();
3502 let rhs = rhs.rb();
3503 let nrows = lhs.nrows();
3504 let ncols = rhs.ncols();
3505 imp(lhs.as_dyn(), rhs.as_dyn().as_dyn_stride())
3506 .into_shape(nrows, ncols)
3507 }
3508 }
3509 });
3510 impl_binop!({
3511 impl<
3512 I: Index,
3513 T: ComplexField,
3514 Rows: Shape,
3515 Depth: Shape,
3516 LT: (Conjugate<Canonical = T>),
3517 RT: (Conjugate<Canonical = T>),
3518 RRStride: Stride,
3519 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Depth>>),
3520 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Depth, RRStride>>),
3521 > Mul<col::generic::Col<R>> for csc::generic::SparseColMat<L>
3522 {
3523 type Output = Col<T, Rows>;
3524
3525 fn mul(self, rhs: _) {
3526 #[track_caller]
3527 fn imp<
3528 I: Index,
3529 T: ComplexField,
3530 LT: Conjugate<Canonical = T>,
3531 RT: Conjugate<Canonical = T>,
3532 >(
3533 lhs: SparseColMatRef<'_, I, LT>,
3534 rhs: ColRef<'_, RT>,
3535 ) -> Col<T> {
3536 let nrows = lhs.nrows();
3537 let mut out = Col::zeros(nrows);
3538 linalg_sp::matmul::sparse_dense_matmul(
3539 out.rb_mut().as_mat_mut(),
3540 Accum::Add,
3541 lhs,
3542 rhs.as_mat(),
3543 T::one_impl(),
3544 crate::Par::Seq,
3545 );
3546 out
3547 }
3548 let lhs = self.rb();
3549 let rhs = rhs.rb();
3550 let nrows = lhs.nrows();
3551 imp(lhs.as_dyn(), rhs.as_dyn_rows().as_dyn_stride())
3552 .into_row_shape(nrows)
3553 }
3554 }
3555 impl<
3556 I: Index,
3557 T: ComplexField,
3558 Rows: Shape,
3559 Depth: Shape,
3560 LT: (Conjugate<Canonical = T>),
3561 RT: (Conjugate<Canonical = T>),
3562 RRStride: Stride,
3563 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Depth>>),
3564 R: (for<'a> Reborrow<'a, Target = col::Ref<'a, RT, Depth, RRStride>>),
3565 > Mul<col::generic::Col<R>> for csr::generic::SparseRowMat<L>
3566 {
3567 type Output = Col<T, Rows>;
3568
3569 fn mul(self, rhs: _) {
3570 #[track_caller]
3571 fn imp<
3572 I: Index,
3573 T: ComplexField,
3574 LT: Conjugate<Canonical = T>,
3575 RT: Conjugate<Canonical = T>,
3576 >(
3577 lhs: SparseRowMatRef<'_, I, LT>,
3578 rhs: ColRef<'_, RT>,
3579 ) -> Col<T> {
3580 let nrows = lhs.nrows();
3581 let mut out = Col::zeros(nrows);
3582 linalg_sp::matmul::dense_sparse_matmul(
3583 out.rb_mut().transpose_mut().as_mat_mut(),
3584 Accum::Add,
3585 rhs.transpose().as_mat(),
3586 lhs.transpose(),
3587 T::one_impl(),
3588 crate::Par::Seq,
3589 );
3590 out
3591 }
3592 let lhs = self.rb();
3593 let rhs = rhs.rb();
3594 let nrows = lhs.nrows();
3595 imp(lhs.as_dyn(), rhs.as_dyn_rows().as_dyn_stride())
3596 .into_row_shape(nrows)
3597 }
3598 }
3599 });
3600 impl_binop!({
3601 impl<
3602 I: Index,
3603 T: ComplexField,
3604 Rows: Shape,
3605 Dim: Shape,
3606 LT: (Conjugate<Canonical = T>),
3607 RT: (Conjugate<Canonical = T>),
3608 RStride: Stride,
3609 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Dim>>),
3610 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
3611 > Mul<diag::generic::Diag<R>> for csc::generic::SparseColMat<L>
3612 {
3613 type Output = SparseColMat<I, T, Rows, Dim>;
3614
3615 fn mul(self, rhs: _) {
3616 #[track_caller]
3617 fn imp<
3618 I: Index,
3619 T: ComplexField,
3620 LT: Conjugate<Canonical = T>,
3621 RT: Conjugate<Canonical = T>,
3622 >(
3623 lhs: SparseColMatRef<'_, I, LT>,
3624 rhs: DiagRef<'_, RT>,
3625 ) -> SparseColMat<I, T> {
3626 with_dim!(M, lhs.nrows());
3627 with_dim!(N, lhs.ncols());
3628 let lhs = lhs.as_shape(M, N);
3629 let rhs = rhs.as_shape(N);
3630 let symbolic = lhs.symbolic().to_owned().unwrap();
3631 let mut out = alloc::vec::Vec::new();
3632 out.resize(symbolic.row_idx().len(), T::zero_impl());
3633 for j in lhs.ncols().indices() {
3634 let ref rhs = Conj::apply(&rhs[j]);
3635 for (out, lhs) in iter::zip(
3636 &mut out[symbolic.col_range(j)],
3637 lhs.val_of_col(j),
3638 ) {
3639 *out = Conj::apply(lhs) * rhs;
3640 }
3641 }
3642 SparseColMat::new(symbolic, out).into_shape(*M, *N)
3643 }
3644 let lhs = self.rb();
3645 let rhs = rhs.rb().column_vector();
3646 let (nrows, ncols) = lhs.shape();
3647 imp(
3648 lhs.as_dyn(),
3649 rhs.as_dyn_rows().as_dyn_stride().as_diagonal(),
3650 )
3651 .into_shape(nrows, ncols)
3652 }
3653 }
3654 impl<
3655 I: Index,
3656 T: ComplexField,
3657 Rows: Shape,
3658 Dim: Shape,
3659 LT: (Conjugate<Canonical = T>),
3660 RT: (Conjugate<Canonical = T>),
3661 RStride: Stride,
3662 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Dim>>),
3663 R: (for<'a> Reborrow<'a, Target = diag::Ref<'a, RT, Dim, RStride>>),
3664 > Mul<diag::generic::Diag<R>> for csr::generic::SparseRowMat<L>
3665 {
3666 type Output = SparseRowMat<I, T, Rows, Dim>;
3667
3668 fn mul(self, rhs: _) {
3669 #[track_caller]
3670 fn imp<
3671 I: Index,
3672 T: ComplexField,
3673 LT: Conjugate<Canonical = T>,
3674 RT: Conjugate<Canonical = T>,
3675 >(
3676 lhs: SparseRowMatRef<'_, I, LT>,
3677 rhs: DiagRef<'_, RT>,
3678 ) -> SparseRowMat<I, T> {
3679 with_dim!(M, lhs.nrows());
3680 with_dim!(N, lhs.ncols());
3681 let lhs = lhs.as_shape(M, N);
3682 let rhs = rhs.as_shape(N);
3683 let symbolic = lhs.symbolic().to_owned().unwrap();
3684 let mut out = alloc::vec::Vec::new();
3685 out.resize(symbolic.col_idx().len(), T::zero_impl());
3686 for i in lhs.nrows().indices() {
3687 for ((j, out), lhs) in iter::zip(
3688 iter::zip(
3689 symbolic.col_idx_of_row(i),
3690 &mut out[symbolic.row_range(i)],
3691 ),
3692 lhs.val_of_row(i),
3693 ) {
3694 *out = Conj::apply(lhs) * Conj::apply(&rhs[j]);
3695 }
3696 }
3697 SparseRowMat::new(symbolic, out).into_shape(*M, *N)
3698 }
3699 let lhs = self.rb();
3700 let rhs = rhs.rb().column_vector();
3701 let (nrows, ncols) = lhs.shape();
3702 imp(
3703 lhs.as_dyn(),
3704 rhs.as_dyn_rows().as_dyn_stride().as_diagonal(),
3705 )
3706 .into_shape(nrows, ncols)
3707 }
3708 }
3709 });
3710 impl_binop!({
3711 impl<
3712 I: Index,
3713 T: ComplexField,
3714 Rows: Shape,
3715 Dim: Shape,
3716 LT: (Conjugate<Canonical = T>),
3717 L: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, LT, Rows, Dim>>),
3718 R: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Dim>>),
3719 > Mul<perm::generic::Perm<R>> for csc::generic::SparseColMat<L>
3720 {
3721 type Output = SparseColMat<I, T, Rows, Dim>;
3722
3723 fn mul(self, rhs: _) {
3724 #[track_caller]
3725 fn imp<
3726 I: Index,
3727 T: ComplexField,
3728 LT: Conjugate<Canonical = T>,
3729 >(
3730 lhs: SparseColMatRef<'_, I, LT>,
3731 rhs: PermRef<'_, I>,
3732 ) -> SparseColMat<I, T> {
3733 with_dim!(M, lhs.nrows());
3734 with_dim!(N, lhs.ncols());
3735 let lhs = lhs.as_shape(M, N);
3736 let rhs = rhs.as_shape(N);
3737 let symbolic = lhs.symbolic();
3738 let mut out_col_ptr = alloc::vec::Vec::new();
3739 let mut out_row_idx = alloc::vec::Vec::new();
3740 let mut out = alloc::vec::Vec::new();
3741 out_col_ptr
3742 .resize(symbolic.col_ptr().len(), I::truncate(0));
3743 out_row_idx
3744 .resize(symbolic.col_ptr().len(), I::truncate(0));
3745 out.resize(
3746 symbolic.row_idx().len(),
3747 T::Canonical::zero_impl(),
3748 );
3749 let inv = rhs.bound_arrays().1;
3750 let mut pos = 0usize;
3751 for j in lhs.ncols().indices() {
3752 let inv = inv[j].zx();
3753 let row_idx = lhs.as_dyn().row_idx_of_col_raw(*inv);
3754 let len = row_idx.len();
3755 out_row_idx[pos..][..len].copy_from_slice(row_idx);
3756 for (out, lhs) in iter::zip(
3757 &mut out[pos..][..len],
3758 lhs.val_of_col(inv),
3759 ) {
3760 *out = Conj::apply(lhs);
3761 }
3762 pos += row_idx.len();
3763 }
3764 out_row_idx.truncate(pos);
3765 out.truncate(pos);
3766 SparseColMat::new(
3767 unsafe {
3768 SymbolicSparseColMat::new_unchecked(
3769 symbolic.nrows(),
3770 symbolic.ncols(),
3771 out_col_ptr,
3772 None,
3773 out_row_idx,
3774 )
3775 },
3776 out,
3777 )
3778 .into_shape(*M, *N)
3779 }
3780 let lhs = self.rb();
3781 let rhs = rhs.rb();
3782 let (nrows, ncols) = lhs.shape();
3783 imp(lhs.as_dyn(), rhs.as_shape(ncols.unbound()))
3784 .into_shape(nrows, ncols)
3785 }
3786 }
3787 impl<
3788 I: Index,
3789 T: ComplexField,
3790 Rows: Shape,
3791 Dim: Shape,
3792 LT: (Conjugate<Canonical = T>),
3793 L: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, LT, Rows, Dim>>),
3794 R: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Dim>>),
3795 > Mul<perm::generic::Perm<R>> for csr::generic::SparseRowMat<L>
3796 {
3797 type Output = SparseRowMat<I, T, Rows, Dim>;
3798
3799 fn mul(self, rhs: _) {
3800 #[track_caller]
3801 fn imp<
3802 I: Index,
3803 T: ComplexField,
3804 LT: Conjugate<Canonical = T>,
3805 >(
3806 lhs: SparseRowMatRef<'_, I, LT>,
3807 rhs: PermRef<'_, I>,
3808 ) -> SparseRowMat<I, T> {
3809 with_dim!(M, lhs.nrows());
3810 with_dim!(N, lhs.ncols());
3811 let lhs = lhs.as_shape(M, N);
3812 let rhs = rhs.as_shape(N);
3813 let symbolic = lhs.symbolic();
3814 let mut out_row_ptr = alloc::vec::Vec::new();
3815 let mut out_col_idx = alloc::vec::Vec::new();
3816 let mut out = alloc::vec::Vec::new();
3817 out_row_ptr
3818 .resize(symbolic.row_ptr().len(), I::truncate(0));
3819 out_col_idx
3820 .resize(symbolic.row_ptr().len(), I::truncate(0));
3821 out.resize(
3822 symbolic.col_idx().len(),
3823 T::Canonical::zero_impl(),
3824 );
3825 let inv = rhs.bound_arrays().0;
3826 let mut pos = 0usize;
3827 for i in lhs.nrows().indices() {
3828 let col_idx = lhs.col_idx_of_row_raw(i);
3829 let len = col_idx.len();
3830 for ((out_j, out_v), (lhs_j, lhs_v)) in iter::zip(
3831 iter::zip(
3832 &mut out_col_idx[pos..][..len],
3833 &mut out[pos..][..len],
3834 ),
3835 iter::zip(lhs.col_idx_of_row(i), lhs.val_of_row(i)),
3836 ) {
3837 *out_j = *inv[lhs_j];
3838 *out_v = Conj::apply(lhs_v);
3839 }
3840 pos += col_idx.len();
3841 }
3842 out_col_idx.truncate(pos);
3843 out.truncate(pos);
3844 SparseRowMat::new(
3845 unsafe {
3846 SymbolicSparseRowMat::new_unchecked(
3847 symbolic.nrows(),
3848 symbolic.ncols(),
3849 out_row_ptr,
3850 None,
3851 out_col_idx,
3852 )
3853 },
3854 out,
3855 )
3856 .into_shape(*M, *N)
3857 }
3858 let lhs = self.rb();
3859 let rhs = rhs.rb();
3860 let (nrows, ncols) = lhs.shape();
3861 imp(lhs.as_dyn(), rhs.as_shape(ncols.unbound()))
3862 .into_shape(nrows, ncols)
3863 }
3864 }
3865 });
3866 impl_binop!({
3867 impl<
3868 I: Index,
3869 T: ComplexField,
3870 Cols: Shape,
3871 Dim: Shape,
3872 RT: (Conjugate<Canonical = T>),
3873 L: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Dim>>),
3874 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Dim, Cols>>),
3875 > Mul<csc::generic::SparseColMat<R>> for perm::generic::Perm<L>
3876 {
3877 type Output = SparseColMat<I, T, Dim, Cols>;
3878
3879 fn mul(self, rhs: _) {
3880 (rhs.rb().transpose() * self.rb().inverse()).into_transpose()
3881 }
3882 }
3883 impl<
3884 I: Index,
3885 T: ComplexField,
3886 Cols: Shape,
3887 Dim: Shape,
3888 RT: (Conjugate<Canonical = T>),
3889 L: (for<'a> Reborrow<'a, Target = perm::Ref<'a, I, Dim>>),
3890 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Dim, Cols>>),
3891 > Mul<csr::generic::SparseRowMat<R>> for perm::generic::Perm<L>
3892 {
3893 type Output = SparseRowMat<I, T, Dim, Cols>;
3894
3895 fn mul(self, rhs: _) {
3896 (rhs.rb().transpose() * self.rb().inverse()).into_transpose()
3897 }
3898 }
3899 });
3900 impl_binop!({
3901 impl<
3902 I: Index,
3903 T: ComplexField,
3904 Cols: Shape,
3905 Dim: Shape,
3906 LT: (Conjugate<Canonical = T>),
3907 RT: (Conjugate<Canonical = T>),
3908 LStride: Stride,
3909 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
3910 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Dim, Cols>>),
3911 > Mul<csc::generic::SparseColMat<R>> for diag::generic::Diag<L>
3912 {
3913 type Output = SparseColMat<I, T, Dim, Cols>;
3914
3915 fn mul(self, rhs: _) {
3916 #[track_caller]
3917 fn imp<
3918 I: Index,
3919 T: ComplexField,
3920 LT: Conjugate<Canonical = T>,
3921 RT: Conjugate<Canonical = T>,
3922 >(
3923 lhs: DiagRef<'_, LT>,
3924 rhs: SparseColMatRef<'_, I, RT>,
3925 ) -> SparseColMat<I, T> {
3926 (rhs.transpose() * lhs).into_transpose()
3927 }
3928 let lhs = self.rb().column_vector();
3929 let rhs = rhs.rb();
3930 let (nrows, ncols) = rhs.shape();
3931 imp(
3932 lhs.as_dyn_rows().as_dyn_stride().as_diagonal(),
3933 rhs.as_dyn(),
3934 )
3935 .into_shape(nrows, ncols)
3936 }
3937 }
3938 impl<
3939 I: Index,
3940 T: ComplexField,
3941 Cols: Shape,
3942 Dim: Shape,
3943 LT: (Conjugate<Canonical = T>),
3944 RT: (Conjugate<Canonical = T>),
3945 LStride: Stride,
3946 L: (for<'a> Reborrow<'a, Target = diag::Ref<'a, LT, Dim, LStride>>),
3947 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Dim, Cols>>),
3948 > Mul<csr::generic::SparseRowMat<R>> for diag::generic::Diag<L>
3949 {
3950 type Output = SparseRowMat<I, T, Dim, Cols>;
3951
3952 fn mul(self, rhs: _) {
3953 #[track_caller]
3954 fn imp<
3955 I: Index,
3956 T: ComplexField,
3957 LT: Conjugate<Canonical = T>,
3958 RT: Conjugate<Canonical = T>,
3959 >(
3960 lhs: DiagRef<'_, LT>,
3961 rhs: SparseRowMatRef<'_, I, RT>,
3962 ) -> SparseRowMat<I, T> {
3963 (rhs.transpose() * lhs).into_transpose()
3964 }
3965 let lhs = self.rb().column_vector();
3966 let rhs = rhs.rb();
3967 let (nrows, ncols) = rhs.shape();
3968 imp(
3969 lhs.as_dyn_rows().as_dyn_stride().as_diagonal(),
3970 rhs.as_dyn(),
3971 )
3972 .into_shape(nrows, ncols)
3973 }
3974 }
3975 });
3976 impl_binop!({
3977 impl<
3978 I: Index,
3979 T: ComplexField,
3980 Rows: Shape,
3981 Cols: Shape,
3982 Depth: Shape,
3983 LT: (Conjugate<Canonical = T>),
3984 LRStride: Stride,
3985 LCStride: Stride,
3986 RT: (Conjugate<Canonical = T>),
3987 L: (for<'a> Reborrow<
3988 'a,
3989 Target = mat::Ref<'a, LT, Rows, Depth, LRStride, LCStride>,
3990 >),
3991 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Depth, Cols>>),
3992 > Mul<csc::generic::SparseColMat<R>> for mat::generic::Mat<L>
3993 {
3994 type Output = Mat<T, Rows, Cols>;
3995
3996 fn mul(self, rhs: _) {
3997 #[track_caller]
3998 fn imp<
3999 I: Index,
4000 T: ComplexField,
4001 LT: Conjugate<Canonical = T>,
4002 RT: Conjugate<Canonical = T>,
4003 >(
4004 lhs: MatRef<'_, LT>,
4005 rhs: SparseColMatRef<'_, I, RT>,
4006 ) -> Mat<T> {
4007 let nrows = lhs.nrows();
4008 let ncols = rhs.ncols();
4009 let mut out = Mat::zeros(nrows, ncols);
4010 linalg_sp::matmul::dense_sparse_matmul(
4011 out.rb_mut(),
4012 Accum::Add,
4013 lhs,
4014 rhs,
4015 T::one_impl(),
4016 crate::Par::Seq,
4017 );
4018 out
4019 }
4020 let lhs = self.rb();
4021 let rhs = rhs.rb();
4022 let nrows = lhs.nrows();
4023 let ncols = rhs.ncols();
4024 imp(lhs.as_dyn().as_dyn_stride(), rhs.as_dyn())
4025 .into_shape(nrows, ncols)
4026 }
4027 }
4028 impl<
4029 I: Index,
4030 T: ComplexField,
4031 Rows: Shape,
4032 Cols: Shape,
4033 Depth: Shape,
4034 LT: (Conjugate<Canonical = T>),
4035 LRStride: Stride,
4036 LCStride: Stride,
4037 RT: (Conjugate<Canonical = T>),
4038 L: (for<'a> Reborrow<
4039 'a,
4040 Target = mat::Ref<'a, LT, Rows, Depth, LRStride, LCStride>,
4041 >),
4042 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Depth, Cols>>),
4043 > Mul<csr::generic::SparseRowMat<R>> for mat::generic::Mat<L>
4044 {
4045 type Output = Mat<T, Rows, Cols>;
4046
4047 fn mul(self, rhs: _) {
4048 #[track_caller]
4049 fn imp<
4050 I: Index,
4051 T: ComplexField,
4052 LT: Conjugate<Canonical = T>,
4053 RT: Conjugate<Canonical = T>,
4054 >(
4055 lhs: MatRef<'_, LT>,
4056 rhs: SparseRowMatRef<'_, I, RT>,
4057 ) -> Mat<T> {
4058 let nrows = lhs.nrows();
4059 let ncols = rhs.ncols();
4060 let mut out = Mat::zeros(nrows, ncols);
4061 linalg_sp::matmul::sparse_dense_matmul(
4062 out.rb_mut().transpose_mut(),
4063 Accum::Add,
4064 rhs.transpose(),
4065 lhs.transpose(),
4066 T::one_impl(),
4067 crate::Par::Seq,
4068 );
4069 out
4070 }
4071 let lhs = self.rb();
4072 let rhs = rhs.rb();
4073 let nrows = lhs.nrows();
4074 let ncols = rhs.ncols();
4075 imp(lhs.as_dyn().as_dyn_stride(), rhs.as_dyn())
4076 .into_shape(nrows, ncols)
4077 }
4078 }
4079 });
4080 impl_binop!({
4081 impl<
4082 I: Index,
4083 T: ComplexField,
4084 Cols: Shape,
4085 Depth: Shape,
4086 LT: (Conjugate<Canonical = T>),
4087 LCStride: Stride,
4088 RT: (Conjugate<Canonical = T>),
4089 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Depth, LCStride>>),
4090 R: (for<'a> Reborrow<'a, Target = csc::Ref<'a, I, RT, Depth, Cols>>),
4091 > Mul<csc::generic::SparseColMat<R>> for row::generic::Row<L>
4092 {
4093 type Output = Row<T, Cols>;
4094
4095 fn mul(self, rhs: _) {
4096 #[track_caller]
4097 fn imp<
4098 I: Index,
4099 T: ComplexField,
4100 LT: Conjugate<Canonical = T>,
4101 RT: Conjugate<Canonical = T>,
4102 >(
4103 lhs: RowRef<'_, LT>,
4104 rhs: SparseColMatRef<'_, I, RT>,
4105 ) -> Row<T> {
4106 let ncols = rhs.ncols();
4107 let mut out = Row::zeros(ncols);
4108 linalg_sp::matmul::dense_sparse_matmul(
4109 out.rb_mut().as_mat_mut(),
4110 Accum::Add,
4111 lhs.as_mat(),
4112 rhs,
4113 T::one_impl(),
4114 crate::Par::Seq,
4115 );
4116 out
4117 }
4118 let lhs = self.rb();
4119 let rhs = rhs.rb();
4120 let ncols = rhs.ncols();
4121 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs.as_dyn())
4122 .into_col_shape(ncols)
4123 }
4124 }
4125 impl<
4126 I: Index,
4127 T: ComplexField,
4128 Cols: Shape,
4129 Depth: Shape,
4130 LT: (Conjugate<Canonical = T>),
4131 LCStride: Stride,
4132 RT: (Conjugate<Canonical = T>),
4133 L: (for<'a> Reborrow<'a, Target = row::Ref<'a, LT, Depth, LCStride>>),
4134 R: (for<'a> Reborrow<'a, Target = csr::Ref<'a, I, RT, Depth, Cols>>),
4135 > Mul<csr::generic::SparseRowMat<R>> for row::generic::Row<L>
4136 {
4137 type Output = Row<T, Cols>;
4138
4139 fn mul(self, rhs: _) {
4140 #[track_caller]
4141 fn imp<
4142 I: Index,
4143 T: ComplexField,
4144 LT: Conjugate<Canonical = T>,
4145 RT: Conjugate<Canonical = T>,
4146 >(
4147 lhs: RowRef<'_, LT>,
4148 rhs: SparseRowMatRef<'_, I, RT>,
4149 ) -> Row<T> {
4150 let ncols = rhs.ncols();
4151 let mut out = Row::zeros(ncols);
4152 linalg_sp::matmul::sparse_dense_matmul(
4153 out.rb_mut().transpose_mut().as_mat_mut(),
4154 Accum::Add,
4155 rhs.transpose(),
4156 lhs.transpose().as_mat(),
4157 T::one_impl(),
4158 crate::Par::Seq,
4159 );
4160 out
4161 }
4162 let lhs = self.rb();
4163 let rhs = rhs.rb();
4164 let ncols = rhs.ncols();
4165 imp(lhs.as_dyn_cols().as_dyn_stride(), rhs.as_dyn())
4166 .into_col_shape(ncols)
4167 }
4168 }
4169 });
4170 fn add_fn<
4171 T: ComplexField,
4172 LhsT: Conjugate<Canonical = T>,
4173 RhsT: Conjugate<Canonical = T>,
4174 >(
4175 lhs: Option<&LhsT>,
4176 rhs: Option<&RhsT>,
4177 ) -> T {
4178 lhs.map(Conj::apply).unwrap_or_else(zero::<T>)
4179 + rhs.map(Conj::apply).unwrap_or_else(zero::<T>)
4180 }
4181 fn sub_fn<
4182 T: ComplexField,
4183 LhsT: Conjugate<Canonical = T>,
4184 RhsT: Conjugate<Canonical = T>,
4185 >(
4186 lhs: Option<&LhsT>,
4187 rhs: Option<&RhsT>,
4188 ) -> T {
4189 lhs.map(Conj::apply).unwrap_or_else(zero::<T>)
4190 - rhs.map(Conj::apply).unwrap_or_else(zero::<T>)
4191 }
4192 fn add_assign_fn<T: ComplexField, RhsT: Conjugate<Canonical = T>>(
4193 dst: &mut T,
4194 rhs: Option<&RhsT>,
4195 ) {
4196 if let Some(rhs) = rhs {
4197 *dst += Conj::apply(rhs);
4198 }
4199 }
4200 fn sub_assign_fn<T: ComplexField, RhsT: Conjugate<Canonical = T>>(
4201 dst: &mut T,
4202 rhs: Option<&RhsT>,
4203 ) {
4204 if let Some(rhs) = rhs {
4205 *dst -= Conj::apply(rhs);
4206 }
4207 }
4208}
4209#[cfg(test)]
4210#[allow(non_snake_case)]
4211mod test {
4212 use crate::assert;
4213 use crate::col::*;
4214 use crate::internal_prelude::*;
4215 use crate::mat::*;
4216 use crate::perm::*;
4217 use crate::row::*;
4218 use assert_approx_eq::assert_approx_eq;
4219 fn matrices() -> (Mat<f64>, Mat<f64>) {
4220 let A = mat![[2.8, -3.3], [-1.7, 5.2], [4.6, -8.3],];
4221 let B = mat![[-7.9, 8.3], [4.7, -3.2], [3.8, -5.2],];
4222 (A, B)
4223 }
4224 fn rows() -> (Row<f64>, Row<f64>) {
4225 (row![2.8, -3.3], row![-7.9, 8.3])
4226 }
4227 fn cols() -> (Col<f64>, Col<f64>) {
4228 (col![2.8, -3.3], col![-7.9, 8.3])
4229 }
4230 #[test]
4231 #[should_panic]
4232 fn test_adding_matrices_of_different_sizes_should_panic() {
4233 let A = mat![[1.0, 2.0], [3.0, 4.0]];
4234 let B = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
4235 _ = A + B;
4236 }
4237 #[test]
4238 #[should_panic]
4239 fn test_subtracting_two_matrices_of_different_sizes_should_panic() {
4240 let A = mat![[1.0, 2.0], [3.0, 4.0]];
4241 let B = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
4242 _ = A - B;
4243 }
4244 #[test]
4245 fn test_matrix_add() {
4246 let (A, B) = matrices();
4247 let expected = mat![[-5.1, 5.0], [3.0, 2.0], [8.4, -13.5],];
4248 assert_matrix_approx_eq(A.as_ref() + B.as_ref(), &expected);
4249 assert_matrix_approx_eq(&A + &B, &expected);
4250 assert_matrix_approx_eq(A.as_ref() + &B, &expected);
4251 assert_matrix_approx_eq(&A + B.as_ref(), &expected);
4252 assert_matrix_approx_eq(A.as_ref() + B.clone(), &expected);
4253 assert_matrix_approx_eq(&A + B.clone(), &expected);
4254 assert_matrix_approx_eq(A.clone() + B.as_ref(), &expected);
4255 assert_matrix_approx_eq(A.clone() + &B, &expected);
4256 assert_matrix_approx_eq(A + B, &expected);
4257 }
4258 #[test]
4259 fn test_row_add() {
4260 let (A, B) = rows();
4261 let expected = row![-5.1, 5.0];
4262 assert_row_approx_eq(A.as_ref() + B.as_ref(), &expected);
4263 assert_row_approx_eq(&A + &B, &expected);
4264 assert_row_approx_eq(A.as_ref() + &B, &expected);
4265 assert_row_approx_eq(&A + B.as_ref(), &expected);
4266 assert_row_approx_eq(A.as_ref() + B.clone(), &expected);
4267 assert_row_approx_eq(A.clone() + B.as_ref(), &expected);
4268 assert_row_approx_eq(&A + B.clone(), &expected);
4269 assert_row_approx_eq(A.clone() + &B, &expected);
4270 assert_row_approx_eq(A + B, &expected);
4271 }
4272 #[test]
4273 fn test_col_add() {
4274 let (A, B) = cols();
4275 let expected = col![-5.1, 5.0];
4276 assert_col_approx_eq(A.as_ref() + B.as_ref(), &expected);
4277 assert_col_approx_eq(&A + &B, &expected);
4278 assert_col_approx_eq(A.as_ref() + &B, &expected);
4279 assert_col_approx_eq(&A + B.as_ref(), &expected);
4280 assert_col_approx_eq(A.as_ref() + B.clone(), &expected);
4281 assert_col_approx_eq(A.clone() + B.as_ref(), &expected);
4282 assert_col_approx_eq(&A + B.clone(), &expected);
4283 assert_col_approx_eq(A.clone() + &B, &expected);
4284 assert_col_approx_eq(A + B, &expected);
4285 }
4286 #[test]
4287 fn test_matrix_sub() {
4288 let (A, B) = matrices();
4289 let expected = mat![[10.7, -11.6], [-6.4, 8.4], [0.8, -3.1],];
4290 assert_matrix_approx_eq(A.as_ref() - B.as_ref(), &expected);
4291 assert_matrix_approx_eq(&A - &B, &expected);
4292 assert_matrix_approx_eq(A.as_ref() - &B, &expected);
4293 assert_matrix_approx_eq(&A - B.as_ref(), &expected);
4294 assert_matrix_approx_eq(A.as_ref() - B.clone(), &expected);
4295 assert_matrix_approx_eq(&A - B.clone(), &expected);
4296 assert_matrix_approx_eq(A.clone() - B.as_ref(), &expected);
4297 assert_matrix_approx_eq(A.clone() - &B, &expected);
4298 assert_matrix_approx_eq(A - B, &expected);
4299 }
4300 #[test]
4301 fn test_row_sub() {
4302 let (A, B) = rows();
4303 let expected = row![10.7, -11.6];
4304 assert_row_approx_eq(A.as_ref() - B.as_ref(), &expected);
4305 assert_row_approx_eq(&A - &B, &expected);
4306 assert_row_approx_eq(A.as_ref() - &B, &expected);
4307 assert_row_approx_eq(&A - B.as_ref(), &expected);
4308 assert_row_approx_eq(A.as_ref() - B.clone(), &expected);
4309 assert_row_approx_eq(A.clone() - B.as_ref(), &expected);
4310 assert_row_approx_eq(&A - B.clone(), &expected);
4311 assert_row_approx_eq(A.clone() - &B, &expected);
4312 assert_row_approx_eq(A - B, &expected);
4313 }
4314 #[test]
4315 fn test_col_sub() {
4316 let (A, B) = cols();
4317 let expected = col![10.7, -11.6];
4318 assert_col_approx_eq(A.as_ref() - B.as_ref(), &expected);
4319 assert_col_approx_eq(&A - &B, &expected);
4320 assert_col_approx_eq(A.as_ref() - &B, &expected);
4321 assert_col_approx_eq(&A - B.as_ref(), &expected);
4322 assert_col_approx_eq(A.as_ref() - B.clone(), &expected);
4323 assert_col_approx_eq(A.clone() - B.as_ref(), &expected);
4324 assert_col_approx_eq(&A - B.clone(), &expected);
4325 assert_col_approx_eq(A.clone() - &B, &expected);
4326 assert_col_approx_eq(A - B, &expected);
4327 }
4328 #[test]
4329 fn test_neg() {
4330 let (A, _) = matrices();
4331 let expected = mat![[-2.8, 3.3], [1.7, -5.2], [-4.6, 8.3],];
4332 assert!(-A == expected);
4333 }
4334 #[test]
4335 fn test_scalar_mul() {
4336 use crate::Scale as scale;
4337 let (A, _) = matrices();
4338 let k = 3.0;
4339 let expected =
4340 Mat::from_fn(A.nrows(), A.ncols(), |i, j| A.as_ref()[(i, j)] * k);
4341 {
4342 assert_matrix_approx_eq(A.as_ref() * scale(k), &expected);
4343 assert_matrix_approx_eq(&A * scale(k), &expected);
4344 assert_matrix_approx_eq(A.as_ref() * scale(k), &expected);
4345 assert_matrix_approx_eq(&A * scale(k), &expected);
4346 assert_matrix_approx_eq(A.as_ref() * scale(k), &expected);
4347 assert_matrix_approx_eq(&A * scale(k), &expected);
4348 assert_matrix_approx_eq(A.clone() * scale(k), &expected);
4349 assert_matrix_approx_eq(A.clone() * scale(k), &expected);
4350 assert_matrix_approx_eq(A * scale(k), &expected);
4351 }
4352 let (A, _) = matrices();
4353 {
4354 assert_matrix_approx_eq(scale(k) * A.as_ref(), &expected);
4355 assert_matrix_approx_eq(scale(k) * &A, &expected);
4356 assert_matrix_approx_eq(scale(k) * A.as_ref(), &expected);
4357 assert_matrix_approx_eq(scale(k) * &A, &expected);
4358 assert_matrix_approx_eq(scale(k) * A.as_ref(), &expected);
4359 assert_matrix_approx_eq(scale(k) * &A, &expected);
4360 assert_matrix_approx_eq(scale(k) * A.clone(), &expected);
4361 assert_matrix_approx_eq(scale(k) * A.clone(), &expected);
4362 assert_matrix_approx_eq(scale(k) * A, &expected);
4363 }
4364 }
4365 #[test]
4366 fn test_diag_mul() {
4367 let (A, _) = matrices();
4368 let diag_left = mat![[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]];
4369 let diag_right = mat![[4.0, 0.0], [0.0, 5.0]];
4370 assert!(&diag_left * &A == diag_left.as_ref().diagonal() * &A);
4371 assert!(&A * &diag_right == &A * diag_right.as_ref().diagonal());
4372 }
4373 #[test]
4374 fn test_perm_mul() {
4375 let A = Mat::from_fn(6, 5, |i, j| (j + 5 * i) as f64);
4376 let pl = Perm::<usize>::new_checked(
4377 Box::new([5, 1, 4, 0, 2, 3]),
4378 Box::new([3, 1, 4, 5, 2, 0]),
4379 6,
4380 );
4381 let pr = Perm::<usize>::new_checked(
4382 Box::new([1, 4, 0, 2, 3]),
4383 Box::new([2, 0, 3, 4, 1]),
4384 5,
4385 );
4386 let perm_left = mat![
4387 [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
4388 [0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
4389 [0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
4390 [1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
4391 [0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
4392 [0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
4393 ];
4394 let perm_right = mat![
4395 [0.0, 1.0, 0.0, 0.0, 0.0],
4396 [0.0, 0.0, 0.0, 0.0, 1.0],
4397 [1.0, 0.0, 0.0, 0.0, 0.0],
4398 [0.0, 0.0, 1.0, 0.0, 0.0],
4399 [0.0, 0.0, 0.0, 1.0, 0.0],
4400 ];
4401 assert!(
4402 &pl * pl.as_ref().inverse()
4403 == PermRef::<'_, usize>::new_checked(
4404 &[0, 1, 2, 3, 4, 5],
4405 &[0, 1, 2, 3, 4, 5],
4406 6
4407 )
4408 );
4409 assert!(&perm_left * &A == &pl * &A);
4410 assert!(&A * &perm_right == &A * &pr);
4411 }
4412 #[test]
4413 fn test_matmul_col_row() {
4414 let A = Col::from_fn(6, |i| i as f64);
4415 let B = Row::from_fn(6, |j| (5 * j + 1) as f64);
4416 assert!(&A * &B == A.as_mat() * B.as_mat());
4417 assert!(&B * &A == (B.as_mat() * A.as_mat())[(0, 0)],);
4418 }
4419 fn assert_row_approx_eq(given: Row<f64>, expected: &Row<f64>) {
4420 assert_eq!(given.nrows(), expected.nrows());
4421 for i in 0..given.nrows() {
4422 assert_approx_eq!(given.as_ref()[i], expected.as_ref()[i]);
4423 }
4424 }
4425 fn assert_col_approx_eq(given: Col<f64>, expected: &Col<f64>) {
4426 assert_eq!(given.ncols(), expected.ncols());
4427 for i in 0..given.ncols() {
4428 assert_approx_eq!(given.as_ref()[i], expected.as_ref()[i]);
4429 }
4430 }
4431 fn assert_matrix_approx_eq(given: Mat<f64>, expected: &Mat<f64>) {
4432 assert_eq!(given.nrows(), expected.nrows());
4433 assert_eq!(given.ncols(), expected.ncols());
4434 for i in 0..given.nrows() {
4435 for j in 0..given.ncols() {
4436 assert_approx_eq!(
4437 given.as_ref()[(i, j)],
4438 expected.as_ref()[(i, j)]
4439 );
4440 }
4441 }
4442 }
4443}