示例#1
0
      // Returns number of valid points in the completed subtree
      int build_tree(int depth, Eigen::VectorXd& rho, 
                     ps_point* z_init, ps_point& z_propose, nuts_util& util)
      {
        
        // Base case
        if (depth == 0) 
        {
          
          this->_integrator.evolve(this->_z, this->_hamiltonian, 
                                   util.sign * this->_epsilon);
          
          rho += this->_z.p;
          
          if (z_init) *z_init = this->_z;
          z_propose = static_cast<ps_point>(this->_z);
          
          double h = this->_hamiltonian.H(this->_z); 
          if (h != h) h = std::numeric_limits<double>::infinity();
          
          util.criterion = util.log_u + (h - util.H0) < this->_max_delta;

          util.sum_prob += stan::math::min(1, std::exp(util.H0 - h));
          util.n_tree += 1;
          
          return (util.log_u + (h - util.H0) < 0);
          
        } 
        // General recursion
        else 
        {
          
          Eigen::VectorXd subtree_rho = Eigen::VectorXd::Zero(rho.size());
          ps_point z_init(this->_z);
          
          int n1 = build_tree(depth - 1, subtree_rho, &z_init, z_propose, util);

          rho += subtree_rho;
          
          if (!util.criterion) return 0;
          
          subtree_rho.setZero();
          ps_point z_propose_right(z_init);
          
          int n2 = build_tree(depth - 1, subtree_rho, 0, z_propose_right, util);
          
          rho += subtree_rho;
          
          double accept_prob = static_cast<double>(n2) /
                               static_cast<double>(n1 + n2);
          
          if ( util.criterion && (this->_rand_uniform() < accept_prob) )
            z_propose = z_propose_right;
          
          util.criterion &= _compute_criterion(z_init, this->_z, rho);
          
          return n1 + n2;
          
        }
        
      }
示例#2
0
      // Returns number of valid points in the completed subtree
      int build_tree(int depth, Eigen::VectorXd& rho,
                     ps_point* z_init_parent, ps_point& z_propose,
                     nuts_util& util) {
        // Base case
        if (depth == 0) {
            this->integrator_.evolve(this->z_, this->hamiltonian_,
                                     util.sign * this->epsilon_);
            rho += this->z_.p;

            if (z_init_parent) *z_init_parent = this->z_;
            z_propose = this->z_;

            double h = this->hamiltonian_.H(this->z_);
            if (boost::math::isnan(h))
              h = std::numeric_limits<double>::infinity();

            util.criterion = util.log_u + (h - util.H0) < this->max_delta_;
            if (!util.criterion) ++(this->n_divergent_);

            util.sum_prob += stan::math::min(1, std::exp(util.H0 - h));
            util.n_tree += 1;

            return (util.log_u + (h - util.H0) < 0);

          } else {
          // General recursion
          Eigen::VectorXd left_subtree_rho(rho.size());
          left_subtree_rho.setZero();
          ps_point z_init(this->z_);

          int n1 = build_tree(depth - 1, left_subtree_rho, &z_init,
                              z_propose, util);

          if (z_init_parent) *z_init_parent = z_init;

          if (!util.criterion) return 0;

          Eigen::VectorXd right_subtree_rho(rho.size());
          right_subtree_rho.setZero();
          ps_point z_propose_right(z_init);

          int n2 = build_tree(depth - 1, right_subtree_rho, 0,
                              z_propose_right, util);

          double accept_prob = static_cast<double>(n2) /
            static_cast<double>(n1 + n2);

          if ( util.criterion && (this->rand_uniform_() < accept_prob) )
            z_propose = z_propose_right;

          Eigen::VectorXd& subtree_rho = left_subtree_rho;
          subtree_rho += right_subtree_rho;

          rho += subtree_rho;

          util.criterion &= compute_criterion(z_init, this->z_, subtree_rho);

          return n1 + n2;
        }
      }