{"action":"created","comment":{"url":"https://api.github.com/repos/stan-dev/stan/pulls/comments/59496664","id":59496664,"diff_hunk":"@@ -0,0 +1,223 @@\n+#ifndef STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP\n+#define STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP\n+\n+#include <stan/interface_callbacks/writer/base_writer.hpp>\n+#include <boost/math/special_functions/fpclassify.hpp>\n+#include <stan/mcmc/hmc/base_hmc.hpp>\n+#include <stan/mcmc/hmc/hamiltonians/ps_point.hpp>\n+#include <algorithm>\n+#include <cmath>\n+#include <limits>\n+#include <string>\n+#include <vector>\n+\n+namespace stan {\n+  namespace mcmc {\n+    /**\n+      * Exhaustive Hamiltonian Monte Carlo (XHMC) with multinomial sampling\n+    */\n+    template <class Model, template<class, class> class Hamiltonian,\n+              template<class> class Integrator, class BaseRNG>\n+    class base_xhmc : public base_hmc<Model, Hamiltonian, Integrator, BaseRNG> {\n+    public:\n+      base_xhmc(Model &model, BaseRNG& rng)\n+        : base_hmc<Model, Hamiltonian, Integrator, BaseRNG>(model, rng),\n+          depth_(0), max_depth_(5), max_deltaH_(1000), x_delta_(0.1),\n+          n_leapfrog_(0), divergent_(0), energy_(0) {\n+      }\n+\n+      ~base_xhmc() {}\n+\n+      void set_max_depth(int d) {\n+        if (d > 0)\n+          max_depth_ = d;\n+      }\n+\n+      void set_max_deltaH(double d) {\n+        max_deltaH_ = d;\n+      }\n+\n+      void set_x_delta(double d) {\n+      if (d > 0)\n+        x_delta_ = d;\n+      }\n+\n+      int get_max_depth() { return this->max_depth_; }\n+      double get_max_deltaH() { return this->max_deltaH_; }\n+      double get_x_delta() { return this->x_delta_; }\n+\n+      sample transition(sample& init_sample,\n+                        interface_callbacks::writer::base_writer& writer) {\n+        // Initialize the algorithm\n+        this->sample_stepsize();\n+\n+        this->seed(init_sample.cont_params());\n+\n+        this->hamiltonian_.sample_p(this->z_, this->rand_int_);\n+        this->hamiltonian_.init(this->z_, writer);\n+\n+        ps_point z_plus(this->z_);\n+        ps_point z_minus(z_plus);\n+\n+        ps_point z_sample(z_plus);\n+        ps_point z_propose(z_plus);\n+\n+        double sum_numer = this->hamiltonian_.dG_dt(this->z_);\n+        double sum_weight = 1;\n+\n+        double H0 = this->hamiltonian_.H(this->z_);\n+        int n_leapfrog = 0;\n+        double sum_metro_prob = 1;  // exp(H0 - H0)\n+\n+        // Build a trajectory until the NUTS criterion is no longer satisfied\n+        this->depth_ = 0;\n+        this->divergent_ = 0;\n+\n+        while (this->depth_ < this->max_depth_) {\n+          // Build a new subtree in a random direction\n+          bool valid_subtree = false;\n+          double sum_numer_subtree = 0;\n+          double sum_weight_subtree = 0;\n+\n+          if (this->rand_uniform_() > 0.5) {\n+            this->z_.ps_point::operator=(z_plus);\n+            valid_subtree\n+              = build_tree(this->depth_, z_propose,\n+                           sum_numer_subtree, sum_weight_subtree,\n+                           H0, 1, n_leapfrog, sum_metro_prob, writer);\n+            z_plus.ps_point::operator=(this->z_);\n+          } else {\n+            this->z_.ps_point::operator=(z_minus);\n+            valid_subtree\n+              = build_tree(this->depth_, z_propose,\n+                           sum_numer_subtree, sum_weight_subtree,\n+                           H0, -1, n_leapfrog, sum_metro_prob, writer);\n+            z_minus.ps_point::operator=(this->z_);\n+          }\n+\n+          sum_numer += sum_numer_subtree;\n+          sum_weight += sum_weight_subtree;\n+          if (!valid_subtree) break;\n+\n+          // Sample from an accepted subtree\n+          ++(this->depth_);\n+\n+          double accept_prob = sum_weight_subtree / sum_weight;\n+          if (this->rand_uniform_() < accept_prob)\n+            z_sample = z_propose;\n+\n+            // Break if exhaustion criterion is satisfied\n+            if (std::fabs(sum_numer / sum_weight) < x_delta_)\n+              break;\n+        }\n+\n+        this->n_leapfrog_ = n_leapfrog;\n+\n+        // Compute average acceptance probabilty across entire trajectory,\n+        // even over subtrees that may have been rejected\n+        double accept_prob\n+          = sum_metro_prob / static_cast<double>(n_leapfrog + 1);\n+\n+        this->z_.ps_point::operator=(z_sample);\n+        this->energy_ = this->hamiltonian_.H(this->z_);\n+        return sample(this->z_.q, -this->z_.V, accept_prob);\n+      }\n+","path":"src/stan/mcmc/hmc/xhmc/base_xhmc.hpp","position":125,"original_position":125,"commit_id":"1177933aa2555a9c895e470d3d2b0a019062f1e5","original_commit_id":"1177933aa2555a9c895e470d3d2b0a019062f1e5","user":{"login":"bob-carpenter","id":3383807,"avatar_url":"https://avatars.githubusercontent.com/u/3383807?v=3","gravatar_id":"","url":"https://api.github.com/users/bob-carpenter","html_url":"https://github.com/bob-carpenter","followers_url":"https://api.github.com/users/bob-carpenter/followers","following_url":"https://api.github.com/users/bob-carpenter/following{/other_user}","gists_url":"https://api.github.com/users/bob-carpenter/gists{/gist_id}","starred_url":"https://api.github.com/users/bob-carpenter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bob-carpenter/subscriptions","organizations_url":"https://api.github.com/users/bob-carpenter/orgs","repos_url":"https://api.github.com/users/bob-carpenter/repos","events_url":"https://api.github.com/users/bob-carpenter/events{/privacy}","received_events_url":"https://api.github.com/users/bob-carpenter/received_events","type":"User","site_admin":false},"body":"This is really awesome.  The algorithm's as clean (if not cleaner) in C++ than in the paper's pseudocode!","created_at":"2016-04-13T06:11:37Z","updated_at":"2016-04-13T06:11:37Z","html_url":"https://github.com/stan-dev/stan/pull/1859#discussion_r59496664","pull_request_url":"https://api.github.com/repos/stan-dev/stan/pulls/1859","_links":{"self":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/comments/59496664"},"html":{"href":"https://github.com/stan-dev/stan/pull/1859#discussion_r59496664"},"pull_request":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/1859"}}},"pull_request":{"url":"https://api.github.com/repos/stan-dev/stan/pulls/1859","id":66129157,"html_url":"https://github.com/stan-dev/stan/pull/1859","diff_url":"https://github.com/stan-dev/stan/pull/1859.diff","patch_url":"https://github.com/stan-dev/stan/pull/1859.patch","issue_url":"https://api.github.com/repos/stan-dev/stan/issues/1859","number":1859,"state":"open","locked":false,"title":"Feature/issue 1855 add xhmc","user":{"login":"betanalpha","id":1527190,"avatar_url":"https://avatars.githubusercontent.com/u/1527190?v=3","gravatar_id":"","url":"https://api.github.com/users/betanalpha","html_url":"https://github.com/betanalpha","followers_url":"https://api.github.com/users/betanalpha/followers","following_url":"https://api.github.com/users/betanalpha/following{/other_user}","gists_url":"https://api.github.com/users/betanalpha/gists{/gist_id}","starred_url":"https://api.github.com/users/betanalpha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/betanalpha/subscriptions","organizations_url":"https://api.github.com/users/betanalpha/orgs","repos_url":"https://api.github.com/users/betanalpha/repos","events_url":"https://api.github.com/users/betanalpha/events{/privacy}","received_events_url":"https://api.github.com/users/betanalpha/received_events","type":"User","site_admin":false},"body":"#### Submisison Checklist\r\n\r\n- [x] Run unit tests: `./runTests.py src/test/unit`\r\n- [x] Run cpplint: `make cpplint`\r\n- [x] Declare copyright holder and open-source license: see below\r\n\r\n#### Summary\r\n\r\nIntroduces Exhaustive Hamiltonian Monte Carlo (XHMC), an algorithm with a similar dynamic integration time scheme to NUTS but with a different termination criterion.\r\n\r\n#### Intended Effect\r\n\r\nNew sampler implementation in the MCMC code with some service support in case we expose it later.\r\n\r\n#### How to Verify\r\n\r\nRun unit tests.\r\n\r\n#### Side Effects\r\n\r\nMCMC tests were reorganized and cleaned up.\r\n\r\n#### Documentation\r\n\r\nNone as we haven't exposed it yet.\r\n\r\n#### Reviewer Suggestions\r\n\r\nAnyone.\r\n\r\n#### Copyright and Licensing\r\n\r\nCopyright: Michael Betancourt\r\n\r\nBy submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses:\r\n- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)\r\n- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)","created_at":"2016-04-12T09:51:20Z","updated_at":"2016-04-13T06:11:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f8174f3fa4a0178ffe510f6576cab43866ebdd45","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/stan-dev/stan/pulls/1859/commits","review_comments_url":"https://api.github.com/repos/stan-dev/stan/pulls/1859/comments","review_comment_url":"https://api.github.com/repos/stan-dev/stan/pulls/comments{/number}","comments_url":"https://api.github.com/repos/stan-dev/stan/issues/1859/comments","statuses_url":"https://api.github.com/repos/stan-dev/stan/statuses/1177933aa2555a9c895e470d3d2b0a019062f1e5","head":{"label":"stan-dev:feature/issue-1855-add_xhmc","ref":"feature/issue-1855-add_xhmc","sha":"1177933aa2555a9c895e470d3d2b0a019062f1e5","user":{"login":"stan-dev","id":3374820,"avatar_url":"https://avatars.githubusercontent.com/u/3374820?v=3","gravatar_id":"","url":"https://api.github.com/users/stan-dev","html_url":"https://github.com/stan-dev","followers_url":"https://api.github.com/users/stan-dev/followers","following_url":"https://api.github.com/users/stan-dev/following{/other_user}","gists_url":"https://api.github.com/users/stan-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/stan-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stan-dev/subscriptions","organizations_url":"https://api.github.com/users/stan-dev/orgs","repos_url":"https://api.github.com/users/stan-dev/repos","events_url":"https://api.github.com/users/stan-dev/events{/privacy}","received_events_url":"https://api.github.com/users/stan-dev/received_events","type":"Organization","site_admin":false},"repo":{"id":8043756,"name":"stan","full_name":"stan-dev/stan","owner":{"login":"stan-dev","id":3374820,"avatar_url":"https://avatars.githubusercontent.com/u/3374820?v=3","gravatar_id":"","url":"https://api.github.com/users/stan-dev","html_url":"https://github.com/stan-dev","followers_url":"https://api.github.com/users/stan-dev/followers","following_url":"https://api.github.com/users/stan-dev/following{/other_user}","gists_url":"https://api.github.com/users/stan-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/stan-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stan-dev/subscriptions","organizations_url":"https://api.github.com/users/stan-dev/orgs","repos_url":"https://api.github.com/users/stan-dev/repos","events_url":"https://api.github.com/users/stan-dev/events{/privacy}","received_events_url":"https://api.github.com/users/stan-dev/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/stan-dev/stan","description":"Stan development repository (home page is linked below). The master branch contains the current release. The develop branch contains the latest stable development.  See the Developer Process Wiki for details.  ","fork":false,"url":"https://api.github.com/repos/stan-dev/stan","forks_url":"https://api.github.com/repos/stan-dev/stan/forks","keys_url":"https://api.github.com/repos/stan-dev/stan/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stan-dev/stan/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stan-dev/stan/teams","hooks_url":"https://api.github.com/repos/stan-dev/stan/hooks","issue_events_url":"https://api.github.com/repos/stan-dev/stan/issues/events{/number}","events_url":"https://api.github.com/repos/stan-dev/stan/events","assignees_url":"https://api.github.com/repos/stan-dev/stan/assignees{/user}","branches_url":"https://api.github.com/repos/stan-dev/stan/branches{/branch}","tags_url":"https://api.github.com/repos/stan-dev/stan/tags","blobs_url":"https://api.github.com/repos/stan-dev/stan/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stan-dev/stan/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stan-dev/stan/git/refs{/sha}","trees_url":"https://api.github.com/repos/stan-dev/stan/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stan-dev/stan/statuses/{sha}","languages_url":"https://api.github.com/repos/stan-dev/stan/languages","stargazers_url":"https://api.github.com/repos/stan-dev/stan/stargazers","contributors_url":"https://api.github.com/repos/stan-dev/stan/contributors","subscribers_url":"https://api.github.com/repos/stan-dev/stan/subscribers","subscription_url":"https://api.github.com/repos/stan-dev/stan/subscription","commits_url":"https://api.github.com/repos/stan-dev/stan/commits{/sha}","git_commits_url":"https://api.github.com/repos/stan-dev/stan/git/commits{/sha}","comments_url":"https://api.github.com/repos/stan-dev/stan/comments{/number}","issue_comment_url":"https://api.github.com/repos/stan-dev/stan/issues/comments{/number}","contents_url":"https://api.github.com/repos/stan-dev/stan/contents/{+path}","compare_url":"https://api.github.com/repos/stan-dev/stan/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stan-dev/stan/merges","archive_url":"https://api.github.com/repos/stan-dev/stan/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stan-dev/stan/downloads","issues_url":"https://api.github.com/repos/stan-dev/stan/issues{/number}","pulls_url":"https://api.github.com/repos/stan-dev/stan/pulls{/number}","milestones_url":"https://api.github.com/repos/stan-dev/stan/milestones{/number}","notifications_url":"https://api.github.com/repos/stan-dev/stan/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stan-dev/stan/labels{/name}","releases_url":"https://api.github.com/repos/stan-dev/stan/releases{/id}","deployments_url":"https://api.github.com/repos/stan-dev/stan/deployments","created_at":"2013-02-06T03:25:04Z","updated_at":"2016-04-12T13:31:21Z","pushed_at":"2016-04-13T05:50:29Z","git_url":"git://github.com/stan-dev/stan.git","ssh_url":"git@github.com:stan-dev/stan.git","clone_url":"https://github.com/stan-dev/stan.git","svn_url":"https://github.com/stan-dev/stan","homepage":"http://mc-stan.org","size":260148,"stargazers_count":578,"watchers_count":578,"language":"Stan","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":127,"mirror_url":null,"open_issues_count":200,"forks":127,"open_issues":200,"watchers":578,"default_branch":"develop"}},"base":{"label":"stan-dev:develop","ref":"develop","sha":"0f0edcfd6d23c2baedf850445f0380a0212651b0","user":{"login":"stan-dev","id":3374820,"avatar_url":"https://avatars.githubusercontent.com/u/3374820?v=3","gravatar_id":"","url":"https://api.github.com/users/stan-dev","html_url":"https://github.com/stan-dev","followers_url":"https://api.github.com/users/stan-dev/followers","following_url":"https://api.github.com/users/stan-dev/following{/other_user}","gists_url":"https://api.github.com/users/stan-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/stan-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stan-dev/subscriptions","organizations_url":"https://api.github.com/users/stan-dev/orgs","repos_url":"https://api.github.com/users/stan-dev/repos","events_url":"https://api.github.com/users/stan-dev/events{/privacy}","received_events_url":"https://api.github.com/users/stan-dev/received_events","type":"Organization","site_admin":false},"repo":{"id":8043756,"name":"stan","full_name":"stan-dev/stan","owner":{"login":"stan-dev","id":3374820,"avatar_url":"https://avatars.githubusercontent.com/u/3374820?v=3","gravatar_id":"","url":"https://api.github.com/users/stan-dev","html_url":"https://github.com/stan-dev","followers_url":"https://api.github.com/users/stan-dev/followers","following_url":"https://api.github.com/users/stan-dev/following{/other_user}","gists_url":"https://api.github.com/users/stan-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/stan-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stan-dev/subscriptions","organizations_url":"https://api.github.com/users/stan-dev/orgs","repos_url":"https://api.github.com/users/stan-dev/repos","events_url":"https://api.github.com/users/stan-dev/events{/privacy}","received_events_url":"https://api.github.com/users/stan-dev/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/stan-dev/stan","description":"Stan development repository (home page is linked below). The master branch contains the current release. The develop branch contains the latest stable development.  See the Developer Process Wiki for details.  ","fork":false,"url":"https://api.github.com/repos/stan-dev/stan","forks_url":"https://api.github.com/repos/stan-dev/stan/forks","keys_url":"https://api.github.com/repos/stan-dev/stan/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stan-dev/stan/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stan-dev/stan/teams","hooks_url":"https://api.github.com/repos/stan-dev/stan/hooks","issue_events_url":"https://api.github.com/repos/stan-dev/stan/issues/events{/number}","events_url":"https://api.github.com/repos/stan-dev/stan/events","assignees_url":"https://api.github.com/repos/stan-dev/stan/assignees{/user}","branches_url":"https://api.github.com/repos/stan-dev/stan/branches{/branch}","tags_url":"https://api.github.com/repos/stan-dev/stan/tags","blobs_url":"https://api.github.com/repos/stan-dev/stan/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stan-dev/stan/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stan-dev/stan/git/refs{/sha}","trees_url":"https://api.github.com/repos/stan-dev/stan/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stan-dev/stan/statuses/{sha}","languages_url":"https://api.github.com/repos/stan-dev/stan/languages","stargazers_url":"https://api.github.com/repos/stan-dev/stan/stargazers","contributors_url":"https://api.github.com/repos/stan-dev/stan/contributors","subscribers_url":"https://api.github.com/repos/stan-dev/stan/subscribers","subscription_url":"https://api.github.com/repos/stan-dev/stan/subscription","commits_url":"https://api.github.com/repos/stan-dev/stan/commits{/sha}","git_commits_url":"https://api.github.com/repos/stan-dev/stan/git/commits{/sha}","comments_url":"https://api.github.com/repos/stan-dev/stan/comments{/number}","issue_comment_url":"https://api.github.com/repos/stan-dev/stan/issues/comments{/number}","contents_url":"https://api.github.com/repos/stan-dev/stan/contents/{+path}","compare_url":"https://api.github.com/repos/stan-dev/stan/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stan-dev/stan/merges","archive_url":"https://api.github.com/repos/stan-dev/stan/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stan-dev/stan/downloads","issues_url":"https://api.github.com/repos/stan-dev/stan/issues{/number}","pulls_url":"https://api.github.com/repos/stan-dev/stan/pulls{/number}","milestones_url":"https://api.github.com/repos/stan-dev/stan/milestones{/number}","notifications_url":"https://api.github.com/repos/stan-dev/stan/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stan-dev/stan/labels{/name}","releases_url":"https://api.github.com/repos/stan-dev/stan/releases{/id}","deployments_url":"https://api.github.com/repos/stan-dev/stan/deployments","created_at":"2013-02-06T03:25:04Z","updated_at":"2016-04-12T13:31:21Z","pushed_at":"2016-04-13T05:50:29Z","git_url":"git://github.com/stan-dev/stan.git","ssh_url":"git@github.com:stan-dev/stan.git","clone_url":"https://github.com/stan-dev/stan.git","svn_url":"https://github.com/stan-dev/stan","homepage":"http://mc-stan.org","size":260148,"stargazers_count":578,"watchers_count":578,"language":"Stan","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":127,"mirror_url":null,"open_issues_count":200,"forks":127,"open_issues":200,"watchers":578,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/1859"},"html":{"href":"https://github.com/stan-dev/stan/pull/1859"},"issue":{"href":"https://api.github.com/repos/stan-dev/stan/issues/1859"},"comments":{"href":"https://api.github.com/repos/stan-dev/stan/issues/1859/comments"},"review_comments":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/1859/comments"},"review_comment":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/stan-dev/stan/pulls/1859/commits"},"statuses":{"href":"https://api.github.com/repos/stan-dev/stan/statuses/1177933aa2555a9c895e470d3d2b0a019062f1e5"}}}}