69 #ifndef GMM_DENSE_LU_H 
   70 #define GMM_DENSE_LU_H 
   76 #if defined(GMM_USES_BLAS) || defined(GMM_USES_LAPACK) 
   77   typedef std::vector<BLAS_INT> lapack_ipvt;
 
   79   typedef std::vector<size_type> lapack_ipvt;
 
   92   template <
typename DenseMatrix, 
typename Pvector>
 
   93   size_type lu_factor(DenseMatrix& A, Pvector& ipvt) {
 
   94     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
   95     typedef typename linalg_traits<Pvector>::value_type INT;
 
   96     typedef typename number_traits<T>::magnitude_type R;
 
   97     size_type info(0), i, j, jp, M(mat_nrows(A)), N(mat_ncols(A));
 
  100     size_type NN = std::min(M, N);
 
  101     std::vector<T> c(M), r(N);
 
  103     GMM_ASSERT2(ipvt.size()+1 >= NN, 
"IPVT too small");
 
  104     for (i = 0; i+1 < NN; ++i) ipvt[i] = INT(i);
 
  107       for (j = 0; j+1 < NN; ++j) {
 
  108         R max = gmm::abs(A(j,j)); jp = j;
 
  109         for (i = j+1; i < M; ++i)                   
 
  110           if (gmm::abs(A(i,j)) > max) { jp = i; max = gmm::abs(A(i,j)); }
 
  111         ipvt[j] = INT(jp + 1);
 
  113         if (max == R(0)) { info = j + 1; 
break; }
 
  114         if (jp != j) 
for (i = 0; i < N; ++i) std::swap(A(jp, i), A(j, i));
 
  116         for (i = j+1; i < M; ++i) { A(i, j) /= A(j,j); c[i-j-1] = -A(i, j); }
 
  117         for (i = j+1; i < N; ++i) r[i-j-1] = A(j, i);  
 
  118         rank_one_update(sub_matrix(A, sub_interval(j+1, M-j-1),
 
  121       ipvt[NN-1] = INT(NN);
 
  128   template <
typename DenseMatrix, 
typename VectorB, 
typename VectorX,
 
  130   void lu_solve(
const DenseMatrix &LU, 
const Pvector& pvector, 
 
  131                 VectorX &x, 
const VectorB &b) {
 
  132     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
  134     for(size_type i = 0; i < pvector.size(); ++i) {
 
  135       size_type perm = 
size_type(pvector[i]-1);   
 
  136       if (i != perm) { T aux = x[i]; x[i] = x[perm]; x[perm] = aux; }
 
  139     lower_tri_solve(LU, x, 
true);
 
  140     upper_tri_solve(LU, x, 
false);
 
  143   template <
typename DenseMatrix, 
typename VectorB, 
typename VectorX>
 
  144   void lu_solve(
const DenseMatrix &A, VectorX &x, 
const VectorB &b) {
 
  145     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
  146     const size_type M(mat_nrows(A)), N(mat_ncols(A));
 
  147     if (M == 0 || N == 0)
 
  149     dense_matrix<T> B(M, N);
 
  153     GMM_ASSERT1(!info, 
"Singular system, pivot = " << info);
 
  154     lu_solve(B, ipvt, x, b);
 
  157   template <
typename DenseMatrix, 
typename VectorB, 
typename VectorX,
 
  159   void lu_solve_transposed(
const DenseMatrix &LU, 
const Pvector& pvector, 
 
  160                            VectorX &x, 
const VectorB &b) {
 
  161     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
  163     lower_tri_solve(transposed(LU), x, 
false);
 
  164     upper_tri_solve(transposed(LU), x, 
true);
 
  165     for (
size_type i = pvector.size(); i > 0; --i) {
 
  177   template <
typename DenseMatrixLU, 
typename DenseMatrix, 
typename Pvector>
 
  178   void lu_inverse(
const DenseMatrixLU& LU, 
const Pvector& pvector,
 
  179                   DenseMatrix& AInv, col_major) {
 
  180     typedef typename linalg_traits<DenseMatrixLU>::value_type T;
 
  181     std::vector<T> tmp(pvector.size(), T(0));
 
  182     std::vector<T> result(pvector.size());
 
  183     for(
size_type i = 0; i < pvector.size(); ++i) {
 
  186       copy(result, mat_col(AInv, i));
 
  191   template <
typename DenseMatrixLU, 
typename DenseMatrix, 
typename Pvector>
 
  192   void lu_inverse(
const DenseMatrixLU& LU, 
const Pvector& pvector,
 
  193                   DenseMatrix& AInv, row_major) {
 
  194     typedef typename linalg_traits<DenseMatrixLU>::value_type T;
 
  195     std::vector<T> tmp(pvector.size(), T(0));
 
  196     std::vector<T> result(pvector.size());
 
  197     for(
size_type i = 0; i < pvector.size(); ++i) {
 
  203       lu_solve_transposed(LU, pvector, result, tmp);
 
  204       copy(result, mat_row(AInv, i));
 
  211   template <
typename DenseMatrixLU, 
typename DenseMatrix, 
typename Pvector>
 
  212   void lu_inverse(
const DenseMatrixLU& LU, 
const Pvector& pvector,
 
  213                   const DenseMatrix& AInv_) {
 
  214     DenseMatrix& AInv = 
const_cast<DenseMatrix&
>(AInv_);
 
  215     lu_inverse(LU, pvector, AInv, 
typename principal_orientation_type<
typename 
  216                linalg_traits<DenseMatrix>::sub_orientation>::potype());
 
  221   template <
typename DenseMatrix>
 
  222   typename linalg_traits<DenseMatrix>::value_type
 
  223   lu_inverse(
const DenseMatrix& A_, 
bool doassert = 
true) {
 
  224     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
  225     DenseMatrix& A = 
const_cast<DenseMatrix&
>(A_);
 
  226     const size_type M(mat_nrows(A)), N(mat_ncols(A));
 
  227     if (M == 0 || N == 0)
 
  229     dense_matrix<T> B(M, N);
 
  232     size_type info = lu_factor(B, ipvt);
 
  233     if (doassert) GMM_ASSERT1(!info, 
"Non invertible matrix, pivot = "<<info);
 
  234     if (!info) lu_inverse(B, ipvt, A);
 
  235     return lu_det(B, ipvt);
 
  239   template <
typename DenseMatrixLU, 
typename Pvector>
 
  240   typename linalg_traits<DenseMatrixLU>::value_type
 
  241   lu_det(
const DenseMatrixLU& LU, 
const Pvector &pvector) {
 
  242     typedef typename linalg_traits<DenseMatrixLU>::value_type T;
 
  243     typedef typename linalg_traits<Pvector>::value_type INT;
 
  245     const size_type J=std::min(mat_nrows(LU), mat_ncols(LU));
 
  246     for (size_type j = 0; j < J; ++j)
 
  248     for(INT i = 0; i < INT(pvector.size()); ++i)
 
  249       if (i != pvector[i]-1) { det = -det; }
 
  253   template <
typename DenseMatrix>
 
  254   typename linalg_traits<DenseMatrix>::value_type
 
  255   lu_det(
const DenseMatrix& A) {
 
  256     typedef typename linalg_traits<DenseMatrix>::value_type T;
 
  257     const size_type M(mat_nrows(A)), N(mat_ncols(A));
 
  258     if (M == 0 || N == 0)
 
  260     dense_matrix<T> B(M, N);
 
  264     return lu_det(B, ipvt);
 
void copy(const L1 &l1, L2 &l2)
*/
conjugated_return< L >::return_type conjugated(const L &v)
return a conjugated view of the input matrix or vector.
Householder for dense matrices.
void lu_solve(const DenseMatrix &LU, const Pvector &pvector, VectorX &x, const VectorB &b)
LU Solve : Solve equation Ax=b, given an LU factored matrix.
Optimization for some small cases (inversion of 2x2 matrices etc.)
size_t size_type
used as the common size type in the library