| Prev | Next |  |  |  |  |  | abs_eval.hpp | Headings

abs_eval Source Code

    namespace CppAD { // BEGIN_CPPAD_NAMESPACE
    // BEGIN PROTOTYPE
    template <class Vector>
    Vector abs_eval(
         size_t        n       ,
         size_t        m       ,
         size_t        s       ,
         const Vector& g_hat   ,
         const Vector& g_jac   ,
         const Vector& delta_x )
    // END PROTOTYPE
    {     using std::fabs;
         //
         CPPAD_ASSERT_KNOWN(
              size_t(delta_x.size()) == n,
              "abs_eval: size of delta_x not equal to n"
         );
         CPPAD_ASSERT_KNOWN(
              size_t(g_hat.size()) == m + s,
              "abs_eval: size of g_hat not equal to m + s"
         );
         CPPAD_ASSERT_KNOWN(
              size_t(g_jac.size()) == (m + s) * (n + s),
              "abs_eval: size of g_jac not equal to (m + s)*(n + s)"
         );
    # ifndef NDEBUG
         // Check that partial_u z(x, u) is strictly lower triangular
         for(size_t i = 0; i < s; i++)
         {     for(size_t j = i; j < s; j++)
              {     // index in g_jac of partial of z_i w.r.t u_j
                   // (note that g_jac has n + s elements in each row)
                   size_t index = (m + i) * (n + s) + (n + j);
                   CPPAD_ASSERT_KNOWN(
                        g_jac[index] == 0.0,
                        "abs_eval: partial z_i w.r.t u_j non-zero for i <= j"
                   );
              }
         }
    # endif
         // return value
         Vector g_tilde(m + s);
         //
         // compute z_tilde, the last s components of g_tilde
         for(size_t i = 0; i < s; i++)
         {     // start at z_hat_i
              g_tilde[m + i] = g_hat[m + i];
              // contribution for change x
              for(size_t j = 0; j < n; j++)
              {     // index in g_jac of partial of z_i w.r.t x_j
                   size_t index = (m + i) * (n + s) + j;
                   // add contribution for delta_x_j to z_tilde_i
                   g_tilde[m + i] += g_jac[index] * delta_x[j];
              }
              // contribution for change in u_j for j < i
              for(size_t j = 0; j < i; j++)
              {     // approixmation for change in absolute value
                   double delta_a_j = fabs(g_tilde[m + j]) - fabs(g_hat[m + j]);
                   // index in g_jac of partial of z_i w.r.t u_j
                   size_t index = (m + i) * (n + s) + n + j;
                   // add constribution for delta_a_j to s_tilde_i
                   g_tilde[m + i] += g_jac[index] * delta_a_j;
              }
         }
         //
         // compute y_tilde, the first m components of g_tilde
         for(size_t i = 0; i < m; i++)
         {     // start at y_hat_i
              g_tilde[i] = g_hat[i];
              // contribution for change x
              for(size_t j = 0; j < n; j++)
              {     // index in g_jac of partial of y_i w.r.t x_j
                   size_t index = i * (n + s) + j;
                   // add contribution for delta_x_j to y_tilde_i
                   g_tilde[i] += g_jac[index] * delta_x[j];
              }
              // contribution for change in u_j
              for(size_t j = 0; j < s; j++)
              {     // approximation for change in absolute value
                   double delta_a_j = fabs(g_tilde[m + j]) - fabs(g_hat[m + j]);
                   // index in g_jac of partial of y_i w.r.t u_j
                   size_t index = i * (n + s) + n + j;
                   // add constribution for delta_a_j to s_tilde_i
                   g_tilde[i] += g_jac[index] * delta_a_j;
              }
         }
         return g_tilde;
    }
    } // END_CPPAD_NAMESPACE

Input File: example/abs_normal/abs_eval.omh