faer_lu/partial_pivoting/
reconstruct.rs1use dyn_stack::{PodStack, SizeOverflow, StackReq};
2use faer_core::{
3 assert,
4 mul::triangular,
5 permutation::{Index, PermutationRef},
6 temp_mat_req, temp_mat_uninit, ComplexField, Entity, MatMut, MatRef, Parallelism,
7};
8use reborrow::*;
9use triangular::BlockStructure;
10
11#[track_caller]
12fn reconstruct_impl<I: Index, E: ComplexField>(
13 dst: MatMut<'_, E>,
14 lu_factors: Option<MatRef<'_, E>>,
15 row_perm: PermutationRef<'_, I, E>,
16 parallelism: Parallelism,
17 stack: PodStack<'_>,
18) {
19 let lu_factors = match lu_factors {
20 Some(lu_factors) => lu_factors,
21 None => dst.rb(),
22 };
23
24 let m = lu_factors.nrows();
25 let n = lu_factors.ncols();
26 let size = Ord::min(m, n);
27
28 let (mut lu, _) = temp_mat_uninit::<E>(m, n, stack);
29 let mut lu = lu.as_mut();
30
31 let (l_top, _, l_bot, _) = lu_factors.split_at(size, size);
32 let (u_left, u_right, _, _) = lu_factors.split_at(size, size);
33
34 let (lu_topleft, lu_topright, lu_botleft, _) = lu.rb_mut().split_at_mut(size, size);
35
36 triangular::matmul(
37 lu_topleft,
38 BlockStructure::Rectangular,
39 l_top,
40 BlockStructure::UnitTriangularLower,
41 u_left,
42 BlockStructure::TriangularUpper,
43 None,
44 E::faer_one(),
45 parallelism,
46 );
47 triangular::matmul(
48 lu_topright,
49 BlockStructure::Rectangular,
50 l_top,
51 BlockStructure::UnitTriangularLower,
52 u_right,
53 BlockStructure::Rectangular,
54 None,
55 E::faer_one(),
56 parallelism,
57 );
58 triangular::matmul(
59 lu_botleft,
60 BlockStructure::Rectangular,
61 l_bot,
62 BlockStructure::Rectangular,
63 u_left,
64 BlockStructure::TriangularUpper,
65 None,
66 E::faer_one(),
67 parallelism,
68 );
69
70 faer_core::permutation::permute_rows(dst, lu.rb(), row_perm.inverse());
71}
72
73#[track_caller]
83pub fn reconstruct<I: Index, E: ComplexField>(
84 dst: MatMut<'_, E>,
85 lu_factors: MatRef<'_, E>,
86 row_perm: PermutationRef<'_, I, E>,
87 parallelism: Parallelism,
88 stack: PodStack<'_>,
89) {
90 assert!((dst.nrows(), dst.ncols()) == (lu_factors.nrows(), lu_factors.ncols()));
91 assert!(row_perm.len() == lu_factors.nrows());
92 reconstruct_impl(dst, Some(lu_factors), row_perm, parallelism, stack)
93}
94
95#[track_caller]
104pub fn reconstruct_in_place<I: Index, E: ComplexField>(
105 lu_factors: MatMut<'_, E>,
106 row_perm: PermutationRef<'_, I, E>,
107 parallelism: Parallelism,
108 stack: PodStack<'_>,
109) {
110 assert!(row_perm.len() == lu_factors.nrows());
111 reconstruct_impl(lu_factors, None, row_perm, parallelism, stack)
112}
113
114pub fn reconstruct_req<I: Index, E: Entity>(
117 nrows: usize,
118 ncols: usize,
119 parallelism: Parallelism,
120) -> Result<StackReq, SizeOverflow> {
121 let _ = parallelism;
122 temp_mat_req::<E>(nrows, ncols)
123}
124
125pub fn reconstruct_in_place_req<I: Index, E: Entity>(
128 nrows: usize,
129 ncols: usize,
130 parallelism: Parallelism,
131) -> Result<StackReq, SizeOverflow> {
132 reconstruct_req::<I, E>(nrows, ncols, parallelism)
133}