49 template <
typename T> T lu_det(
const dense_matrix<T> &A) {
52 const T *p = &(A(0,0));
55 case 2 :
return (*p) * (*(p+3)) - (*(p+1)) * (*(p+2));
62 dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
63 lapack_ipvt ipvt(mat_nrows(A));
66 return lu_det(B, ipvt);
74 template <
typename T> T lu_inverse(
const dense_matrix<T> &A_,
75 bool doassert =
true) {
76 dense_matrix<T>& A =
const_cast<dense_matrix<T> &
>(A_);
84 if (doassert) GMM_ASSERT1(det!=T(0),
"non invertible matrix");
85 if (det == T(0))
break;
89 det = (*p) * (*(p+3)) - (*(p+1)) * (*(p+2));
90 if (doassert) GMM_ASSERT1(det!=T(0),
"non invertible matrix");
91 if (det == T(0))
break;
92 std::swap(*p, *(p+3));
93 *p++ /= det; *p++ /= -det; *p++ /= -det; *p++ /= det;
97 T a, b, c, d, e, f, g, h, i;
98 a = (*(p+4)) * (*(p+8)) - (*(p+5)) * (*(p+7));
99 b = - (*(p+1)) * (*(p+8)) + (*(p+2)) * (*(p+7));
100 c = (*(p+1)) * (*(p+5)) - (*(p+2)) * (*(p+4));
101 d = - (*(p+3)) * (*(p+8)) + (*(p+5)) * (*(p+6));
102 e = (*(p+0)) * (*(p+8)) - (*(p+2)) * (*(p+6));
103 f = - (*(p+0)) * (*(p+5)) + (*(p+2)) * (*(p+3));
104 g = (*(p+3)) * (*(p+7)) - (*(p+4)) * (*(p+6));
105 h = - (*(p+0)) * (*(p+7)) + (*(p+1)) * (*(p+6));
106 i = (*(p+0)) * (*(p+4)) - (*(p+1)) * (*(p+3));
107 det = (*p) * a + (*(p+1)) * d + (*(p+2)) * g;
108 if (std::abs(det) > 1e-5) {
109 *p++ = a / det; *p++ = b / det; *p++ = c / det;
110 *p++ = d / det; *p++ = e / det; *p++ = f / det;
111 *p++ = g / det; *p++ = h / det; *p++ = i / det;
115 dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
116 lapack_ipvt ipvt(mat_nrows(A));
119 GMM_ASSERT1(!info,
"non invertible matrix");
120 lu_inverse(B, ipvt, A);
121 det = lu_det(B, ipvt);
132 #endif // GMM_OPT_H__