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