Пример #1
0
    typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type
    multi_gp_cholesky_log(const Eigen::Matrix
                          <T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
                          const Eigen::Matrix
                          <T_covar, Eigen::Dynamic, Eigen::Dynamic>& L,
                          const Eigen::Matrix<T_w, Eigen::Dynamic, 1>& w) {
      static const char* function("multi_gp_cholesky_log");
      typedef
        typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type T_lp;
      T_lp lp(0.0);


      check_size_match(function,
                       "Size of random variable (rows y)", y.rows(),
                       "Size of kernel scales (w)", w.size());
      check_size_match(function,
                       "Size of random variable", y.cols(),
                       "rows of covariance parameter", L.rows());
      check_finite(function, "Kernel scales", w);
      check_positive(function, "Kernel scales", w);
      check_finite(function, "Random variable", y);

      if (y.rows() == 0)
        return lp;

      if (include_summand<propto>::value) {
        lp += NEG_LOG_SQRT_TWO_PI * y.rows() * y.cols();
      }

      if (include_summand<propto, T_covar>::value) {
        lp -= L.diagonal().array().log().sum() * y.rows();
      }

      if (include_summand<propto, T_w>::value) {
        lp += 0.5 * y.cols() * sum(log(w));
      }

      if (include_summand<propto, T_y, T_w, T_covar>::value) {
        T_lp sum_lp_vec(0.0);
        for (int i = 0; i < y.rows(); i++) {
          Eigen::Matrix<T_y, Eigen::Dynamic, 1> y_row(y.row(i));
          Eigen::Matrix<typename boost::math::tools::promote_args
                        <T_y, T_covar>::type,
                        Eigen::Dynamic, 1>
            half(mdivide_left_tri_low(L, y_row));
          sum_lp_vec += w(i) * dot_self(half);
        }
        lp -= 0.5*sum_lp_vec;
      }

      return lp;
    }
Пример #2
0
    typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type
    multi_gp_log(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
                 const Eigen::Matrix
                 <T_covar, Eigen::Dynamic, Eigen::Dynamic>& Sigma,
                 const Eigen::Matrix<T_w, Eigen::Dynamic, 1>& w) {
      static const char* function("multi_gp_log");
      typedef typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type
        T_lp;
      T_lp lp(0.0);


      check_positive(function, "Kernel rows", Sigma.rows());
      check_finite(function, "Kernel", Sigma);
      check_symmetric(function, "Kernel", Sigma);

      LDLT_factor<T_covar, Eigen::Dynamic, Eigen::Dynamic> ldlt_Sigma(Sigma);
      check_ldlt_factor(function, "LDLT_Factor of Sigma", ldlt_Sigma);

      check_size_match(function,
                       "Size of random variable (rows y)", y.rows(),
                       "Size of kernel scales (w)", w.size());
      check_size_match(function,
                       "Size of random variable", y.cols(),
                       "rows of covariance parameter", Sigma.rows());
      check_positive_finite(function, "Kernel scales", w);
      check_finite(function, "Random variable", y);

      if (y.rows() == 0)
        return lp;

      if (include_summand<propto>::value) {
        lp += NEG_LOG_SQRT_TWO_PI * y.rows() * y.cols();
      }

      if (include_summand<propto, T_covar>::value) {
        lp -= 0.5 * log_determinant_ldlt(ldlt_Sigma) * y.rows();
      }

      if (include_summand<propto, T_w>::value) {
        lp += (0.5 * y.cols()) * sum(log(w));
      }

      if (include_summand<propto, T_y, T_w, T_covar>::value) {
        Eigen::Matrix<T_w, Eigen::Dynamic, Eigen::Dynamic>
          w_mat(w.asDiagonal());
        Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic> yT(y.transpose());
        lp -= 0.5 * trace_gen_inv_quad_form_ldlt(w_mat, ldlt_Sigma, yT);
      }

      return lp;
    }
Пример #3
0
 inline bool check_corr_matrix(const char* function,
               const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y,
               const char* name,
               T_result* result,
               const Policy&) {
   if (!check_size_match(function, 
       y.rows(), "Rows of correlation matrix",
       y.cols(), "columns of correlation matrix",
       result, Policy())) 
     return false;
   if (!check_positive(function, y.rows(), "rows", result, Policy()))
     return false;
   if (!check_symmetric(function, y, "y", result, Policy()))
     return false;
   for (typename Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>::size_type
          k = 0; k < y.rows(); ++k) {
     if (fabs(y(k,k) - 1.0) > CONSTRAINT_TOLERANCE) {
       std::ostringstream message;
       message << name << " is not a valid correlation matrix. " 
               << name << "(" << k << "," << k 
               << ") is %1%, but should be near 1.0";
       T_result tmp 
         = policies::raise_domain_error<T_y>(function,
                                             message.str().c_str(),
                                             y(k,k), Policy());
       if (result != 0)
         *result = tmp;
       return false;
     }
   }
   if (!check_pos_definite(function, y, "y", result, Policy()))
     return false;
   return true;
 }
Пример #4
0
 inline bool check_square(const char* function,
              const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y,
              const char* name,
              T_result* result) {
   check_size_match(function, 
                    y.rows(), "Rows of matrix",
                    y.cols(), "columns of matrix",
                    result);
   return true;
 }
Пример #5
0
 inline bool check_matching_sizes(const char* function,
                                  const char* name1,
                                  const T_y1& y1,
                                  const char* name2,
                                  const T_y2& y2) {
   check_size_match(function,
                    "size of ", name1, y1.size(),
                    "size of ", name2, y2.size());
   return true;
 }
Пример #6
0
 inline bool check_cov_matrix(const std::string& function,
                              const std::string& name,
                              const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y) {
   check_size_match(function, 
                    "Rows of covariance matrix", y.rows(),
                    "columns of covariance matrix", y.cols());
   check_positive(function, "rows", y.rows());
   check_symmetric(function, name, y);
   check_pos_definite(function, name, y);
   return true;
 }
Пример #7
0
    inline
    Eigen::Matrix<typename boost::math::tools::promote_args<T1, T2>::type,
                  Eigen::Dynamic, 1>
    csr_matrix_times_vector(const int& m,
                            const int& n,
                            const Eigen::Matrix<T1, Eigen::Dynamic, 1>& w,
                            const std::vector<int>& v,
                            const std::vector<int>& u,
                            const Eigen::Matrix<T2, Eigen::Dynamic, 1>& b) {
      typedef typename boost::math::tools::promote_args<T1, T2>::type
        result_t;

      check_positive("csr_matrix_times_vector", "m", m);
      check_positive("csr_matrix_times_vector", "n", n);
      check_size_match("csr_matrix_times_vector", "n", n, "b", b.size());
      check_size_match("csr_matrix_times_vector", "m", m, "u", u.size() - 1);
      check_size_match("csr_matrix_times_vector", "w", w.size(), "v", v.size());
      check_size_match("csr_matrix_times_vector", "u/z",
                       u[m - 1] + csr_u_to_z(u, m - 1) - 1, "v", v.size());
      for (unsigned int i = 0; i < v.size(); ++i)
        check_range("csr_matrix_times_vector", "v[]", n, v[i]);

      Eigen::Matrix<result_t, Eigen::Dynamic, 1>  result(m);
      result.setZero();
      for (int row = 0; row < m; ++row) {
        int idx = csr_u_to_z(u, row);
        int row_end_in_w = (u[row] - stan::error_index::value) + idx;
        int i = 0;  // index into dot-product segment entries.
        Eigen::Matrix<result_t, Eigen::Dynamic, 1> b_sub(idx);
        b_sub.setZero();
        for (int nze = u[row] - stan::error_index::value;
             nze < row_end_in_w; ++nze, ++i) {
          check_range("csr_matrix_times_vector", "j", n, v[nze]);
          b_sub.coeffRef(i) = b.coeffRef(v[nze] - stan::error_index::value);
        }  // loop skipped when z is zero.
        Eigen::Matrix<T1, Eigen::Dynamic, 1>
          w_sub(w.segment(u[row] - stan::error_index::value, idx));
        result.coeffRef(row) = dot_product(w_sub, b_sub);
      }
      return result;
    }
Пример #8
0
 inline bool check_multiplicable(const char* function,
                                 const char* name1,
                                 const T1& y1,
                                 const char* name2,
                                 const T2& y2) {
   check_positive_size(function, name1, "rows()", y1.rows());
   check_positive_size(function, name2, "cols()", y2.cols());
   check_size_match(function,
                    "Columns of ", name1, y1.cols(),
                    "Rows of ", name2, y2.rows());
   check_positive_size(function, name1, "cols()", y1.cols());
   return true;
 }
Пример #9
0
 inline bool check_cov_matrix(const char* function,
                              const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y,
                              const char* name,
                              T_result* result) {
   check_size_match(function, 
                    y.rows(), "Rows of covariance matrix",
                    y.cols(), "columns of covariance matrix",
                    result);
   check_positive(function, y.rows(), "rows", result);
   check_symmetric(function, y, name, result);
   check_pos_definite(function, y, name, result);
   return true;
 }
Пример #10
0
    typename return_type<T_y, T_loc, T_covar>::type
    multi_normal_cholesky_log(const T_y& y,
                              const T_loc& mu,
                              const T_covar& L) {
      static const char* function("multi_normal_cholesky_log");
      typedef typename scalar_type<T_covar>::type T_covar_elem;
      typedef typename return_type<T_y, T_loc, T_covar>::type lp_type;
      lp_type lp(0.0);


      VectorViewMvt<const T_y> y_vec(y);
      VectorViewMvt<const T_loc> mu_vec(mu);
      size_t size_vec = max_size_mvt(y, mu);

      int size_y = y_vec[0].size();
      int size_mu = mu_vec[0].size();
      if (size_vec > 1) {
        int size_y_old = size_y;
        int size_y_new;
        for (size_t i = 1, size_ = length_mvt(y); i < size_; i++) {
          int size_y_new = y_vec[i].size();
          check_size_match(function,
                           "Size of one of the vectors of "
                           "the random variable", size_y_new,
                           "Size of another vector of the "
                           "random variable", size_y_old);
          size_y_old = size_y_new;
        }
        int size_mu_old = size_mu;
        int size_mu_new;
        for (size_t i = 1, size_ = length_mvt(mu); i < size_; i++) {
          int size_mu_new = mu_vec[i].size();
          check_size_match(function,
                           "Size of one of the vectors of "
                           "the location variable", size_mu_new,
                           "Size of another vector of the "
                           "location variable", size_mu_old);
          size_mu_old = size_mu_new;
        }
        (void) size_y_old;
        (void) size_y_new;
        (void) size_mu_old;
        (void) size_mu_new;
      }

      check_size_match(function,
                       "Size of random variable", size_y,
                       "size of location parameter", size_mu);
      check_size_match(function,
                       "Size of random variable", size_y,
                       "rows of covariance parameter", L.rows());
      check_size_match(function,
                       "Size of random variable", size_y,
                       "columns of covariance parameter", L.cols());

      for (size_t i = 0; i < size_vec; i++) {
        check_finite(function, "Location parameter", mu_vec[i]);
        check_not_nan(function, "Random variable", y_vec[i]);
      }

      if (size_y == 0)
        return lp;

      if (include_summand<propto>::value)
        lp += NEG_LOG_SQRT_TWO_PI * size_y * size_vec;

      if (include_summand<propto, T_covar_elem>::value)
        lp -= L.diagonal().array().log().sum() * size_vec;

      if (include_summand<propto, T_y, T_loc, T_covar_elem>::value) {
        lp_type sum_lp_vec(0.0);
        for (size_t i = 0; i < size_vec; i++) {
          Eigen::Matrix<typename return_type<T_y, T_loc>::type,
                        Eigen::Dynamic, 1> y_minus_mu(size_y);
          for (int j = 0; j < size_y; j++)
            y_minus_mu(j) = y_vec[i](j)-mu_vec[i](j);
          Eigen::Matrix<typename return_type<T_y, T_loc, T_covar>::type,
                        Eigen::Dynamic, 1>
            half(mdivide_left_tri_low(L, y_minus_mu));
          // FIXME: this code does not compile. revert after fixing subtract()
          // Eigen::Matrix<typename
          //               boost::math::tools::promote_args<T_covar,
          //                 typename value_type<T_loc>::type,
          //                 typename value_type<T_y>::type>::type>::type,
          //               Eigen::Dynamic, 1>
          //   half(mdivide_left_tri_low(L, subtract(y, mu)));
          sum_lp_vec += dot_self(half);
        }
        lp -= 0.5*sum_lp_vec;
      }
      return lp;
    }