| Prev | Next |  |  |  |  |  | lu_factor.hpp | Headings

Source: LuFactor
`# ifndef CPPAD_LU_FACTOR_HPP `
` # define CPPAD_LU_FACTOR_HPP

    # include <complex>
    # include <vector>

    # include <cppad/core/cppad_assert.hpp>
    # include <cppad/utility/check_simple_vector.hpp>
    # include <cppad/utility/check_numeric_type.hpp>

    namespace CppAD { // BEGIN CppAD namespace

    // AbsGeq
    template <typename Float>
    inline bool AbsGeq(const Float &x, const Float &y)
    {     Float xabs = x;
         if( xabs <= Float(0) )
              xabs = - xabs;
         Float yabs = y;
         if( yabs <= Float(0) )
              yabs = - yabs;
         return xabs >= yabs;
    }
    inline bool AbsGeq(
         const std::complex<double> &x,
         const std::complex<double> &y)
    {     double xsq = x.real() * x.real() + x.imag() * x.imag();
         double ysq = y.real() * y.real() + y.imag() * y.imag();

         return xsq >= ysq;
    }
    inline bool AbsGeq(
         const std::complex<float> &x,
         const std::complex<float> &y)
    {     float xsq = x.real() * x.real() + x.imag() * x.imag();
         float ysq = y.real() * y.real() + y.imag() * y.imag();

         return xsq >= ysq;
    }

    // Lines that are different from code in cppad/core/lu_ratio.hpp end with //
    template <class SizeVector, class FloatVector>                          //
    int LuFactor(SizeVector &ip, SizeVector &jp, FloatVector &LU)           //
    {
         // type of the elements of LU                                   //
         typedef typename FloatVector::value_type Float;                 //

         // check numeric type specifications
         CheckNumericType<Float>();

         // check simple vector class specifications
         CheckSimpleVector<Float, FloatVector>();
         CheckSimpleVector<size_t, SizeVector>();

         size_t  i, j;          // some temporary indices
         const Float zero( 0 ); // the value zero as a Float object
         size_t  imax;          // row index of maximum element
         size_t  jmax;          // column indx of maximum element
         Float    emax;         // maximum absolute value
         size_t  p;             // count pivots
         int     sign;          // sign of the permutation
         Float   etmp;          // temporary element
         Float   pivot;         // pivot element

         // -------------------------------------------------------
         size_t n = ip.size();
         CPPAD_ASSERT_KNOWN(
              size_t(jp.size()) == n,
              "Error in LuFactor: jp must have size equal to n"
         );
         CPPAD_ASSERT_KNOWN(
              size_t(LU.size()) == n * n,
              "Error in LuFactor: LU must have size equal to n * m"
         );
         // -------------------------------------------------------

         // initialize row and column order in matrix not yet pivoted
         for(i = 0; i < n; i++)
         {     ip[i] = i;
              jp[i] = i;
         }
         // initialize the sign of the permutation
         sign = 1;
         // ---------------------------------------------------------

         // Reduce the matrix P to L * U using n pivots
         for(p = 0; p < n; p++)
         {     // determine row and column corresponding to element of
              // maximum absolute value in remaining part of P
              imax = jmax = n;
              emax = zero;
              for(i = p; i < n; i++)
              {     for(j = p; j < n; j++)
                   {     CPPAD_ASSERT_UNKNOWN(
                             (ip[i] < n) & (jp[j] < n)
                        );
                        etmp = LU[ ip[i] * n + jp[j] ];

                        // check if maximum absolute value so far
                        if( AbsGeq (etmp, emax) )
                        {     imax = i;
                             jmax = j;
                             emax = etmp;
                        }
                   }
              }
              CPPAD_ASSERT_KNOWN(
              (imax < n) & (jmax < n) ,
              "LuFactor can't determine an element with "
              "maximum absolute value.\n"
              "Perhaps original matrix contains not a number or infinity.\n"
              "Perhaps your specialization of AbsGeq is not correct."
              );
              if( imax != p )
              {     // switch rows so max absolute element is in row p
                   i        = ip[p];
                   ip[p]    = ip[imax];
                   ip[imax] = i;
                   sign     = -sign;
              }
              if( jmax != p )
              {     // switch columns so max absolute element is in column p
                   j        = jp[p];
                   jp[p]    = jp[jmax];
                   jp[jmax] = j;
                   sign     = -sign;
              }
              // pivot using the max absolute element
              pivot   = LU[ ip[p] * n + jp[p] ];

              // check for determinant equal to zero
              if( pivot == zero )
              {     // abort the mission
                   return   0;
              }

              // Reduce U by the elementary transformations that maps
              // LU( ip[p], jp[p] ) to one.  Only need transform elements
              // above the diagonal in U and LU( ip[p] , jp[p] ) is
              // corresponding value below diagonal in L.
              for(j = p+1; j < n; j++)
                   LU[ ip[p] * n + jp[j] ] /= pivot;

              // Reduce U by the elementary transformations that maps
              // LU( ip[i], jp[p] ) to zero. Only need transform elements
              // above the diagonal in U and LU( ip[i], jp[p] ) is
              // corresponding value below diagonal in L.
              for(i = p+1; i < n; i++ )
              {     etmp = LU[ ip[i] * n + jp[p] ];
                   for(j = p+1; j < n; j++)
                   {     LU[ ip[i] * n + jp[j] ] -=
                             etmp * LU[ ip[p] * n + jp[j] ];
                   }
              }
         }
         return sign;
    }
    } // END CppAD namespace

# endif`

Input File: omh/lu_factor_hpp.omh