det_of_minor.hpp

Source: det_of_minor

# ifndef CPPAD_DET_OF_MINOR_HPP
# define CPPAD_DET_OF_MINOR_HPP
# include <vector>
# include <cstddef>

namespace CppAD { // BEGIN CppAD namespace
template <class Scalar>
Scalar det_of_minor(
   const std::vector<Scalar>& a  ,
   size_t                     m  ,
   size_t                     n  ,
   std::vector<size_t>&       r  ,
   std::vector<size_t>&       c  )
{
   const size_t R0 = r[m]; // R(0)
   size_t       Cj = c[m]; // C(j)    (case j = 0)
   size_t       Cj1 = m;   // C(j-1)  (case j = 0)

   // check for 1 by 1 case
   if( n == 1 ) return a[ R0 * m + Cj ];

   // initialize determinant of the minor M
   Scalar detM = Scalar(0);

   // initialize sign of factor for next sub-minor
   int s = 1;

   // remove row with index 0 in M from all the sub-minors of M
   r[m] = r[R0];

   // for each column of M
   for(size_t j = 0; j < n; j++)
   {  // element with index (0,j) in the minor M
      Scalar M0j = a[ R0 * m + Cj ];

      // remove column with index j in M to form next sub-minor S of M
      c[Cj1] = c[Cj];

      // compute determinant of the current sub-minor S
      Scalar detS = det_of_minor(a, m, n - 1, r, c);

      // restore column Cj to represenation of M as a minor of A
      c[Cj1] = Cj;

      // include this sub-minor term in the summation
      if( s > 0 )
         detM = detM + M0j * detS;
      else
         detM = detM - M0j * detS;

      // advance to next column of M
      Cj1 = Cj;
      Cj  = c[Cj];
      s   = - s;
   }

   // restore row zero to the minor representation for M
   r[m] = R0;

   // return the determinant of the minor M
   return detM;
}
} // END CppAD namespace

# endif