casadi_det.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 // SYMBOL "det"
21 // Determinant of a matrix from its sparse QR factors (as produced by casadi_qr).
22 // det = det(Q) * det(R) = prod_c (1 - beta(c)*v(:,c)'v(:,c)) * prod_c R(c,c).
23 // The caller multiplies by the (data-independent) sign of the row/column pivoting
24 // to recover the determinant of the original, unpermuted matrix.
25 template<typename T1>
26 T1 casadi_det(const casadi_int* sp_v, const T1* nz_v,
27  const casadi_int* sp_r, const T1* nz_r, const T1* beta) {
28  // Local variables
29  casadi_int ncol, c, k;
30  const casadi_int *v_colind, *r_colind;
31  T1 det, vtv;
32  // Extract sparsities
33  ncol = sp_v[1];
34  v_colind = sp_v+2; r_colind = sp_r+2;
35  // Product of the diagonal entries of R
36  det = 1;
37  for (c=0; c<ncol; ++c) det *= nz_r[r_colind[c+1]-1];
38  // Determinant of Q (product of Householder reflectors)
39  for (c=0; c<ncol; ++c) {
40  vtv = 0;
41  for (k=v_colind[c]; k<v_colind[c+1]; ++k) vtv += nz_v[k]*nz_v[k];
42  det *= 1 - beta[c]*vtv;
43  }
44  return det;
45 }