fix_likelihood.cpp

View page source

Random Likelihood: Example and Test

# include <cppad/cppad.hpp>
# include <cppad/mixed/cppad_mixed.hpp>


namespace {
   using CppAD::log;
   using CppAD::AD;
   //
   using CppAD::mixed::d_sparse_rcv;
   using CppAD::mixed::a1_double;
   using CppAD::mixed::d_vector;
   using CppAD::mixed::a1_vector;
   //
   class mixed_derived : public cppad_mixed {
   private:
      const d_vector&       z_;
   public:
      // constructor
      mixed_derived(
         size_t                 n_fixed       ,
         size_t                 n_random      ,
         bool                   quasi_fixed   ,
         bool                   bool_sparsity ,
         const d_vector&        z             ) :
         cppad_mixed(n_fixed, n_random, quasi_fixed, bool_sparsity) ,
         z_(z)
      { }
      // implementation of fix_likelihood
      a1_vector fix_likelihood(
         const a1_vector&         theta  )
      {
         a1_vector vec(1);

         // compute this factor once
         double sqrt_2pi = CppAD::sqrt( 8.0 * CppAD::atan(1.0) );

         // initialize summation
         vec[0] = 0.0;

         // for each data and random effect
         for(size_t i = 0; i < z_.size(); i++)
         {  a1_double mu     = theta[i];
            a1_double res    = (z_[i] - mu) / 1.0;

            // This is a Gaussian term, so entire density is smooth
            vec[0]  += log(sqrt_2pi) + res * res / 2.0;
         }
         return vec;
      }
   };
}

bool fix_likelihood_xam(void)
{
   bool   ok  = true;
   double pi  = 4.0 * std::atan(1.0);
   double eps = 100. * std::numeric_limits<double>::epsilon();
   //
   // typedef cppad_mixed::a1_double a1_double
   size_t n_data   = 10;
   size_t n_fixed  = n_data;
   size_t n_random = 0;
   d_vector    data(n_data);
   d_vector    fixed_vec(n_fixed), random_vec(n_random);
   a1_vector a1_fixed(n_fixed);

   for(size_t i = 0; i < n_data; i++)
   {  data[i]       = double(i + 1);
      //
      fixed_vec[i]  = 1.5;
      a1_fixed[i]   = a1_double( fixed_vec[i] );
   }

   // object that is derived from cppad_mixed
   bool quasi_fixed   = true;
   bool bool_sparsity = true;
   mixed_derived mixed_object(
      n_fixed, n_random, quasi_fixed, bool_sparsity, data
   );
   mixed_object.initialize(fixed_vec, random_vec);

   // Evaluate fix_likelihood
   a1_vector a1_vec(1);
   a1_vec = mixed_object.fix_likelihood(a1_fixed);

   // check the random likelihood
   double sum = 0.0;
   for(size_t i = 0; i < n_data; i++)
   {  double mu     = fixed_vec[i];
      double res    = (data[i] - mu);
      sum          += (std::log(2 * pi) + res * res) / 2.0;
   }
   ok &= fabs( a1_vec[0] / a1_double(sum) - a1_double(1.0) ) < eps;

   return ok;
}