{"action":"created","comment":{"url":"https://api.github.com/repos/stan-dev/math/pulls/comments/77365521","id":77365521,"diff_hunk":"@@ -0,0 +1,305 @@\n+#ifndef STAN_MATH_REV_MAT_FUN_COV_EXP_QUAD_HPP\n+#define STAN_MATH_REV_MAT_FUN_COV_EXP_QUAD_HPP\n+\n+#include <stan/math/rev/core.hpp>\n+#include <stan/math/rev/scal/fun/value_of.hpp>\n+#include <stan/math/rev/scal/fun/value_of_rec.hpp>\n+#include <stan/math/prim/mat/fun/value_of.hpp>\n+#include <stan/math/prim/mat/fun/value_of_rec.hpp>\n+#include <stan/math/prim/mat/meta/length.hpp>\n+#include <stan/math/prim/arr/meta/length.hpp>\n+#include <stan/math/prim/scal/meta/length.hpp>\n+#include <stan/math/prim/scal/meta/return_type.hpp>\n+#include <stan/math/prim/scal/err/check_size_match.hpp>\n+#include <stan/math/prim/mat/fun/Eigen.hpp>\n+#include <stan/math/prim/mat/fun/squared_distance.hpp>\n+#include <stan/math/prim/scal/err/check_not_nan.hpp>\n+#include <stan/math/prim/scal/err/check_positive.hpp>\n+#include <stan/math/prim/scal/fun/square.hpp>\n+#include <boost/math/tools/promotion.hpp>\n+#include <boost/utility/enable_if.hpp>\n+#include <boost/type_traits.hpp>\n+#include <vector>\n+#include <cmath>\n+\n+namespace stan {\n+  namespace math {\n+\n+    /**\n+     * This is a subclass of the vari class for precomputed\n+     * gradients of cov_exp_quad.\n+     *\n+     * The class stores the double values for the distance\n+     * matrix, pointers to the varis for the covariance\n+     * matrix, along with a pointer to the vari for sigma,\n+     * and the vari for l.\n+     *\n+     * @tparam T_x type of std::vector of elements\n+     * @tparam T_sigma type of sigma\n+     * @tparam T_l type of length scale\n+     */\n+    template <typename T_x, typename T_sigma, typename T_l>\n+    class cov_exp_quad_vari : public vari {\n+      public:\n+        int size_;\n+        int size_vech_;\n+        double l_d_;\n+        double sigma_d_;\n+        double sigma_sq_d_;\n+        double* dist_;\n+        vari* l_vari_;\n+        vari* sigma_vari_;\n+        vari** cov_lower_;\n+        vari** cov_upper_;\n+        vari** cov_diag_;\n+\n+        /**\n+         * Constructor for cov_exp_quad.\n+         *\n+         * All memory allocated in\n+         * ChainableStack's stack_alloc arena.\n+         *\n+         * It is critical for the efficiency of this object\n+         * that the constructor create new varis that aren't\n+         * popped onto the var_stack_, but rather are\n+         * popped onto the var_nochain_stack_. This is\n+         * controlled to the second argument to\n+         * vari's constructor.\n+         *\n+         * @param x std::vector input that can be used in square distance\n+         *    Assumes each element of x is the same size\n+         * @param sigma standard deviation\n+         * @param l length scale\n+         */\n+        cov_exp_quad_vari(const std::vector<T_x>& x,\n+                          const T_sigma& sigma,\n+                          const T_l& l)\n+          : vari(0.0),\n+          size_(x.size()),\n+          size_vech_(size_ * (size_ - 1) / 2),\n+          l_d_(value_of(l)), sigma_d_(value_of(sigma)),\n+          sigma_sq_d_(std::pow(sigma_d_, 2)),\n+          dist_(ChainableStack::memalloc_.alloc_array<double>(size_vech_)),\n+          l_vari_(l.vi_), sigma_vari_(sigma.vi_),\n+          cov_lower_(ChainableStack::memalloc_.alloc_array<vari*>(size_vech_)),\n+          cov_upper_(ChainableStack::memalloc_.alloc_array<vari*>(size_vech_)),\n+          cov_diag_(ChainableStack::memalloc_.alloc_array<vari*>(size_)) {\n+            double inv_half_sq_l_d = 0.5 / (std::pow(l_d_, 2));\n+            size_t pos = 0;\n+            for (size_t j = 0; j < static_cast<size_t>(size_ - 1); ++j) {\n+              for (size_t i = j + 1; i < static_cast<size_t>(size_); ++i) {\n+                double dist_sq = squared_distance(x[i], x[j]);\n+                double val = sigma_sq_d_ * exp(-dist_sq\n+                                              * inv_half_sq_l_d);\n+                dist_[pos] = dist_sq;\n+                cov_upper_[pos] = new vari(val, false);\n+                cov_lower_[pos] = new vari(val, false);\n+                ++pos;\n+              }\n+            }\n+              for (size_t i = 0; i < static_cast<size_t>(size_); ++i)\n+                cov_diag_[i] = new vari(sigma_sq_d_, false);\n+          }\n+\n+        virtual void chain() {\n+          double adjl(0.0);\n+          double adjsigma(0.0);\n+\n+          for (size_t i = 0; i < static_cast<size_t>(size_vech_); ++i) {\n+            vari* el_low = cov_lower_[i];\n+            vari* el_high = cov_upper_[i];\n+            double prod_adj_cov_low = el_low->adj_ * el_low->val_;\n+            double prod_adj_cov_high = el_high->adj_ * el_high->val_;\n+            double prod_add = prod_adj_cov_low + prod_adj_cov_high;\n+            adjl += prod_add * dist_[i];\n+            adjsigma += prod_add;\n+          }\n+          for (size_t i = 0; i < static_cast<size_t>(size_); ++i) {\n+            vari* el = cov_diag_[i];\n+            double prod_adj_cov = el->adj_ * el->val_;\n+            adjsigma += prod_adj_cov;\n+          }\n+          l_vari_->adj_ +=  adjl / std::pow(l_d_, 3);\n+          sigma_vari_->adj_ += adjsigma * 2 / sigma_d_;\n+          }\n+    };\n+\n+    /**\n+     * This is a subclass of the vari class for precomputed\n+     * gradients of cov_exp_quad.\n+     *\n+     * The class stores the double values for the distance\n+     * matrix, pointers to the varis for the covariance\n+     * matrix, along with a pointer to the vari for sigma,\n+     * and the vari for l.\n+     *\n+     * @tparam T_x type of std::vector of elements\n+     * @tparam T_sigma type of sigma\n+     * @tparam T_l type of length scale\n+     */\n+    template <typename T_x, typename T_l>\n+    class cov_exp_quad_vari<T_x, double, T_l> : public vari {\n+      public:\n+        int size_;\n+        int size_vech_;\n+        double l_d_;\n+        double sigma_d_;\n+        double sigma_sq_d_;\n+        double* dist_;\n+        vari* l_vari_;\n+        vari** cov_lower_;\n+        vari** cov_upper_;\n+        vari** cov_diag_;\n+\n+        /**\n+         * Constructor for cov_exp_quad.\n+         *\n+         * All memory allocated in\n+         * ChainableStack's stack_alloc arena.\n+         *\n+         * It is critical for the efficiency of this object\n+         * that the constructor create new varis that aren't\n+         * popped onto the var_stack_, but rather are\n+         * popped onto the var_nochain_stack_. This is\n+         * controlled to the second argument to\n+         * vari's constructor.\n+         *\n+         * @param x std::vector input that can be used in square distance\n+         *    Assumes each element of x is the same size\n+         * @param sigma standard deviation\n+         * @param l length scale\n+         */\n+        cov_exp_quad_vari(const std::vector<T_x>& x,\n+                          double sigma,\n+                          const T_l& l)\n+          : vari(0.0),\n+          size_(x.size()),\n+          size_vech_(size_ * (size_ - 1) / 2),\n+          l_d_(value_of(l)), sigma_d_(value_of(sigma)),\n+          sigma_sq_d_(std::pow(sigma_d_, 2)),\n+          dist_(ChainableStack::memalloc_.alloc_array<double>(size_vech_)),\n+          l_vari_(l.vi_),\n+          cov_lower_(ChainableStack::memalloc_.alloc_array<vari*>(size_vech_)),\n+          cov_upper_(ChainableStack::memalloc_.alloc_array<vari*>(size_vech_)),\n+          cov_diag_(ChainableStack::memalloc_.alloc_array<vari*>(size_)) {\n+            double inv_half_sq_l_d = 0.5 / (std::pow(l_d_, 2));\n+            size_t pos = 0;\n+            for (size_t j = 0; j < static_cast<size_t>(size_ - 1); ++j) {\n+              for (size_t i = j + 1; i < static_cast<size_t>(size_); ++i) {\n+                double dist_sq = squared_distance(x[i], x[j]);\n+                double val = sigma_sq_d_ * exp(-dist_sq\n+                                              * inv_half_sq_l_d);\n+                dist_[pos] = dist_sq;\n+                cov_upper_[pos] = new vari(val, false);\n+                cov_lower_[pos] = new vari(val, false);\n+                ++pos;\n+              }\n+            }\n+              for (size_t i = 0; i < static_cast<size_t>(size_); ++i)\n+                cov_diag_[i] = new vari(sigma_sq_d_, false);\n+          }\n+\n+        virtual void chain() {\n+          double adjl(0.0);\n+\n+          for (size_t i = 0; i < static_cast<size_t>(size_vech_); ++i) {\n+            vari* el_low = cov_lower_[i];\n+            vari* el_high = cov_upper_[i];\n+            double prod_adj_cov_low = el_low->adj_ * el_low->val_;\n+            double prod_adj_cov_high = el_high->adj_ * el_high->val_;\n+            double prod_add = prod_adj_cov_low + prod_adj_cov_high;\n+            adjl += prod_add * dist_[i];\n+          }\n+          l_vari_->adj_ +=  adjl / std::pow(l_d_, 3);\n+        }\n+    };\n+\n+    /**\n+     * Returns a squared exponential kernel.\n+     *\n+     * @param x std::vector input that can be used in square distance\n+     *    Assumes each element of x is the same size\n+     * @param sigma standard deviation\n+     * @param l length scale\n+     * @return squared distance\n+     * @throw std::domain_error if sigma <= 0, l <= 0, or\n+     *   x is nan or infinite\n+     */\n+    inline\n+    Eigen::Matrix<var, -1, -1>\n+    cov_exp_quad(const std::vector<double>& x,\n+                 const var& sigma,\n+                 const var& l) {\n+      check_positive(\"cov_exp_quad\", \"sigma\", sigma);\n+      check_positive(\"cov_exp_quad\", \"l\", l);\n+      for (size_t n = 0; n < x.size(); n++)\n+        check_not_nan(\"cov_exp_quad\", \"x\", x[n]);\n+","path":"stan/math/rev/mat/fun/cov_exp_quad.hpp","position":237,"original_position":237,"commit_id":"6a12c13e084e913b9b97d235268ff62c038f5fac","original_commit_id":"6a12c13e084e913b9b97d235268ff62c038f5fac","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":"I think there's a vector form of `check_not_nan` which will provide better error messages that include the index rather than just saying that `x` is not-a-number.","created_at":"2016-09-02T15:29:40Z","updated_at":"2016-09-02T15:29:40Z","html_url":"https://github.com/stan-dev/math/pull/378#discussion_r77365521","pull_request_url":"https://api.github.com/repos/stan-dev/math/pulls/378","_links":{"self":{"href":"https://api.github.com/repos/stan-dev/math/pulls/comments/77365521"},"html":{"href":"https://github.com/stan-dev/math/pull/378#discussion_r77365521"},"pull_request":{"href":"https://api.github.com/repos/stan-dev/math/pulls/378"}}},"pull_request":{"url":"https://api.github.com/repos/stan-dev/math/pulls/378","id":83812526,"html_url":"https://github.com/stan-dev/math/pull/378","diff_url":"https://github.com/stan-dev/math/pull/378.diff","patch_url":"https://github.com/stan-dev/math/pull/378.patch","issue_url":"https://api.github.com/repos/stan-dev/math/issues/378","number":378,"state":"open","locked":false,"title":"Feature/issue 353 cov exp quad grad","user":{"login":"rtrangucci","id":3925639,"avatar_url":"https://avatars.githubusercontent.com/u/3925639?v=3","gravatar_id":"","url":"https://api.github.com/users/rtrangucci","html_url":"https://github.com/rtrangucci","followers_url":"https://api.github.com/users/rtrangucci/followers","following_url":"https://api.github.com/users/rtrangucci/following{/other_user}","gists_url":"https://api.github.com/users/rtrangucci/gists{/gist_id}","starred_url":"https://api.github.com/users/rtrangucci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rtrangucci/subscriptions","organizations_url":"https://api.github.com/users/rtrangucci/orgs","repos_url":"https://api.github.com/users/rtrangucci/repos","events_url":"https://api.github.com/users/rtrangucci/events{/privacy}","received_events_url":"https://api.github.com/users/rtrangucci/received_events","type":"User","site_admin":false},"body":"#### Submisison Checklist\r\n\r\n- [x] Run unit tests: `./runTests.py 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\nSpecialize gradients for cov_exp_quad:\r\n\r\n- `std::vector<double> x, var sigma, var l`\r\n- `std::vector<double> x, double sigma, var l` \r\n\r\n#### Intended Effect:\r\n\r\nSpeed up gradients by about 40% to 50%\r\n\r\n#### How to Verify:\r\n\r\nUnfortunately, the only way to verify is to exclude `stan/math/rev/mat/fun/cov_exp_quad.hpp` from the includes and run something like below, record the time, and then include `stan/math/rev/mat/fun/cov_exp_quad.hpp`  and look at the diff. Came out to somewhere between 40% and 50% depending on the size of the matrix:\r\n\r\n```\r\n#include <stan/math/rev/mat.hpp>\r\n#include <gtest/gtest.h>\r\n#include <test/unit/math/rev/mat/fun/util.hpp>\r\n#include <sys/time.h>\r\n#include <ctime>\r\n\r\n// returns milliseconds\r\nunsigned int get_time(){\r\n  struct timeval tv;\r\n\r\n  gettimeofday(&tv,NULL);\r\n\r\n  unsigned int ret = tv.tv_usec;\r\n  ret /= 1000;\r\n\r\n  ret += (tv.tv_sec * 1000);\r\n\r\n  return ret;\r\n}\r\n\r\nTEST(AgradRevMatrix, cov_exp_quad_timing) {\r\n  using stan::math::matrix_v;\r\n  using stan::math::var;\r\n  using stan::math::cov_exp_quad;\r\n  using std::vector;\r\n\r\n  unsigned int start, end;\r\n  int n = 1e2;\r\n  double sum_grad(0.0);\r\n  int size = 500;\r\n  Eigen::VectorXd dv = Eigen::VectorXd::Random(size);\r\n  vector<double> vv;\r\n  for (int i = 0; i < size; ++i)\r\n    vv.push_back(dv(i));\r\n\r\n  start = get_time();\r\n  for (int k = 0; k < n; ++k) {\r\n    var sig = 1;\r\n    var len = 2;\r\n    matrix_v cov_mat = cov_exp_quad(vv, sig, len);\r\n\r\n    AVEC ab;\r\n    VEC grad;\r\n    ab.push_back(sig);\r\n    ab.push_back(len);\r\n    \r\n    cov_mat(0,1).grad(ab, grad);\r\n    for (size_t j = 0; j < static_cast<size_t>(grad.size()); ++j)\r\n      sum_grad += grad[j];\r\n    stan::math::recover_memory();\r\n  }\r\n  end = get_time();\r\n  std::cout << sum_grad << std::endl;\r\n  std::cout << end - start << std::endl;\r\n}\r\n```\r\n\r\n#### Side Effects:\r\n\r\nNone.\r\n\r\n#### Documentation:\r\n\r\nNone.\r\n\r\n#### Reviewer Suggestions: \r\n\r\nAnyone.\r\n\r\n#### Copyright and Licensing\r\n\r\nPlease list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):\r\n\r\nRob Trangucci\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-09-02T14:38:10Z","updated_at":"2016-09-02T15:29:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f63b75ad5b6539a909c10bca3928180ee768cdfd","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/stan-dev/math/pulls/378/commits","review_comments_url":"https://api.github.com/repos/stan-dev/math/pulls/378/comments","review_comment_url":"https://api.github.com/repos/stan-dev/math/pulls/comments{/number}","comments_url":"https://api.github.com/repos/stan-dev/math/issues/378/comments","statuses_url":"https://api.github.com/repos/stan-dev/math/statuses/6a12c13e084e913b9b97d235268ff62c038f5fac","head":{"label":"stan-dev:feature/issue-353-cov_exp_quad_grad","ref":"feature/issue-353-cov_exp_quad_grad","sha":"6a12c13e084e913b9b97d235268ff62c038f5fac","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":38388440,"name":"math","full_name":"stan-dev/math","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/math","description":"Stan Math Library","fork":false,"url":"https://api.github.com/repos/stan-dev/math","forks_url":"https://api.github.com/repos/stan-dev/math/forks","keys_url":"https://api.github.com/repos/stan-dev/math/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stan-dev/math/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stan-dev/math/teams","hooks_url":"https://api.github.com/repos/stan-dev/math/hooks","issue_events_url":"https://api.github.com/repos/stan-dev/math/issues/events{/number}","events_url":"https://api.github.com/repos/stan-dev/math/events","assignees_url":"https://api.github.com/repos/stan-dev/math/assignees{/user}","branches_url":"https://api.github.com/repos/stan-dev/math/branches{/branch}","tags_url":"https://api.github.com/repos/stan-dev/math/tags","blobs_url":"https://api.github.com/repos/stan-dev/math/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stan-dev/math/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stan-dev/math/git/refs{/sha}","trees_url":"https://api.github.com/repos/stan-dev/math/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stan-dev/math/statuses/{sha}","languages_url":"https://api.github.com/repos/stan-dev/math/languages","stargazers_url":"https://api.github.com/repos/stan-dev/math/stargazers","contributors_url":"https://api.github.com/repos/stan-dev/math/contributors","subscribers_url":"https://api.github.com/repos/stan-dev/math/subscribers","subscription_url":"https://api.github.com/repos/stan-dev/math/subscription","commits_url":"https://api.github.com/repos/stan-dev/math/commits{/sha}","git_commits_url":"https://api.github.com/repos/stan-dev/math/git/commits{/sha}","comments_url":"https://api.github.com/repos/stan-dev/math/comments{/number}","issue_comment_url":"https://api.github.com/repos/stan-dev/math/issues/comments{/number}","contents_url":"https://api.github.com/repos/stan-dev/math/contents/{+path}","compare_url":"https://api.github.com/repos/stan-dev/math/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stan-dev/math/merges","archive_url":"https://api.github.com/repos/stan-dev/math/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stan-dev/math/downloads","issues_url":"https://api.github.com/repos/stan-dev/math/issues{/number}","pulls_url":"https://api.github.com/repos/stan-dev/math/pulls{/number}","milestones_url":"https://api.github.com/repos/stan-dev/math/milestones{/number}","notifications_url":"https://api.github.com/repos/stan-dev/math/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stan-dev/math/labels{/name}","releases_url":"https://api.github.com/repos/stan-dev/math/releases{/id}","deployments_url":"https://api.github.com/repos/stan-dev/math/deployments","created_at":"2015-07-01T18:40:54Z","updated_at":"2016-08-23T22:54:41Z","pushed_at":"2016-09-02T14:38:10Z","git_url":"git://github.com/stan-dev/math.git","ssh_url":"git@github.com:stan-dev/math.git","clone_url":"https://github.com/stan-dev/math.git","svn_url":"https://github.com/stan-dev/math","homepage":null,"size":220802,"stargazers_count":58,"watchers_count":58,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":74,"forks":20,"open_issues":74,"watchers":58,"default_branch":"develop"}},"base":{"label":"stan-dev:develop","ref":"develop","sha":"7c1fb9a5be14d952fbe35dbcb2f62f023f1171aa","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":38388440,"name":"math","full_name":"stan-dev/math","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/math","description":"Stan Math Library","fork":false,"url":"https://api.github.com/repos/stan-dev/math","forks_url":"https://api.github.com/repos/stan-dev/math/forks","keys_url":"https://api.github.com/repos/stan-dev/math/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stan-dev/math/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stan-dev/math/teams","hooks_url":"https://api.github.com/repos/stan-dev/math/hooks","issue_events_url":"https://api.github.com/repos/stan-dev/math/issues/events{/number}","events_url":"https://api.github.com/repos/stan-dev/math/events","assignees_url":"https://api.github.com/repos/stan-dev/math/assignees{/user}","branches_url":"https://api.github.com/repos/stan-dev/math/branches{/branch}","tags_url":"https://api.github.com/repos/stan-dev/math/tags","blobs_url":"https://api.github.com/repos/stan-dev/math/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stan-dev/math/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stan-dev/math/git/refs{/sha}","trees_url":"https://api.github.com/repos/stan-dev/math/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stan-dev/math/statuses/{sha}","languages_url":"https://api.github.com/repos/stan-dev/math/languages","stargazers_url":"https://api.github.com/repos/stan-dev/math/stargazers","contributors_url":"https://api.github.com/repos/stan-dev/math/contributors","subscribers_url":"https://api.github.com/repos/stan-dev/math/subscribers","subscription_url":"https://api.github.com/repos/stan-dev/math/subscription","commits_url":"https://api.github.com/repos/stan-dev/math/commits{/sha}","git_commits_url":"https://api.github.com/repos/stan-dev/math/git/commits{/sha}","comments_url":"https://api.github.com/repos/stan-dev/math/comments{/number}","issue_comment_url":"https://api.github.com/repos/stan-dev/math/issues/comments{/number}","contents_url":"https://api.github.com/repos/stan-dev/math/contents/{+path}","compare_url":"https://api.github.com/repos/stan-dev/math/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stan-dev/math/merges","archive_url":"https://api.github.com/repos/stan-dev/math/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stan-dev/math/downloads","issues_url":"https://api.github.com/repos/stan-dev/math/issues{/number}","pulls_url":"https://api.github.com/repos/stan-dev/math/pulls{/number}","milestones_url":"https://api.github.com/repos/stan-dev/math/milestones{/number}","notifications_url":"https://api.github.com/repos/stan-dev/math/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stan-dev/math/labels{/name}","releases_url":"https://api.github.com/repos/stan-dev/math/releases{/id}","deployments_url":"https://api.github.com/repos/stan-dev/math/deployments","created_at":"2015-07-01T18:40:54Z","updated_at":"2016-08-23T22:54:41Z","pushed_at":"2016-09-02T14:38:10Z","git_url":"git://github.com/stan-dev/math.git","ssh_url":"git@github.com:stan-dev/math.git","clone_url":"https://github.com/stan-dev/math.git","svn_url":"https://github.com/stan-dev/math","homepage":null,"size":220802,"stargazers_count":58,"watchers_count":58,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":74,"forks":20,"open_issues":74,"watchers":58,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/stan-dev/math/pulls/378"},"html":{"href":"https://github.com/stan-dev/math/pull/378"},"issue":{"href":"https://api.github.com/repos/stan-dev/math/issues/378"},"comments":{"href":"https://api.github.com/repos/stan-dev/math/issues/378/comments"},"review_comments":{"href":"https://api.github.com/repos/stan-dev/math/pulls/378/comments"},"review_comment":{"href":"https://api.github.com/repos/stan-dev/math/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/stan-dev/math/pulls/378/commits"},"statuses":{"href":"https://api.github.com/repos/stan-dev/math/statuses/6a12c13e084e913b9b97d235268ff62c038f5fac"}}}}
{"actor":{"display_login":"bob-carpenter"}}