From 2b942d57258b92124044022ac82c62252adf6606 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sat, 24 Aug 2019 23:47:57 +0200 Subject: [PATCH 01/13] [WIP] Robust U-turn check Following the recent discussion on the Stan side: https://github.com/stan-dev/stan/pull/2800 For experiment, do not merge. --- pymc3/step_methods/hmc/nuts.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index 01e454fb6e..de2ff63318 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -251,10 +251,18 @@ def extend(self, direction): if direction > 0: tree, diverging, turning = self._build_subtree( self.right, self.depth, floatX(np.asarray(self.step_size))) + leftmost_begin, leftmost_end = self.left, self.right + rightmost_begin, rightmost_end = tree.left, tree.right + leftmost_p_sum = self.p_sum + rightmost_p_sum = tree.p_sum self.right = tree.right else: tree, diverging, turning = self._build_subtree( self.left, self.depth, floatX(np.asarray(-self.step_size))) + leftmost_begin, leftmost_end = tree.left, tree.right + rightmost_begin, rightmost_end = self.left, self.right + leftmost_p_sum = tree.p_sum + rightmost_p_sum = self.p_sum self.left = tree.right self.depth += 1 @@ -274,8 +282,12 @@ def extend(self, direction): left, right = self.left, self.right p_sum = self.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = leftmost_p_sum + rightmost_begin.p + turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) + p_sum2 = leftmost_end.p + rightmost_p_sum + turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) - return diverging, turning + return diverging, (turning | turning1 | turning2) def _single_step(self, left, epsilon): """Perform a leapfrog step and handle error cases.""" @@ -324,6 +336,10 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = tree1.p_sum + tree2.left.p + turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) + p_sum2 = tree1.right.p + tree2.p_sum + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.rigth.v) <= 0) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): @@ -340,7 +356,7 @@ def _build_subtree(self, left, depth, epsilon): tree = Subtree(left, right, p_sum, proposal, log_size, accept_sum, n_proposals) - return tree, diverging, turning + return tree, diverging, (turning | turning1 | turning2) def stats(self): return { From b0af43c68f30da143e8bb526a824a57d00ed6f51 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 07:38:45 +0200 Subject: [PATCH 02/13] typo fix --- pymc3/step_methods/hmc/nuts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index de2ff63318..1a79047d20 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -339,7 +339,7 @@ def _build_subtree(self, left, depth, epsilon): p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) p_sum2 = tree1.right.p + tree2.p_sum - turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.rigth.v) <= 0) + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): From ae9d56ce8c91aa247ec5980eea0bf72291498e3d Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 08:05:20 +0200 Subject: [PATCH 03/13] bug fix --- pymc3/step_methods/hmc/nuts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index 1a79047d20..e51f3dcd09 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -335,11 +335,12 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum - turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + turning0 = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) p_sum2 = tree1.right.p + tree2.p_sum turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) + turning = (turning0 | turning1 | turning2) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): @@ -356,7 +357,7 @@ def _build_subtree(self, left, depth, epsilon): tree = Subtree(left, right, p_sum, proposal, log_size, accept_sum, n_proposals) - return tree, diverging, (turning | turning1 | turning2) + return tree, diverging, turning def stats(self): return { From 995724b9f87a451614ed420fb70c64158bb9a654 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 09:44:39 +0200 Subject: [PATCH 04/13] Additional U turn check only when depth > 1 (to avoid redundant work). --- pymc3/step_methods/hmc/nuts.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index e51f3dcd09..ff7c845b19 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -335,12 +335,14 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum - turning0 = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - p_sum1 = tree1.p_sum + tree2.left.p - turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) - p_sum2 = tree1.right.p + tree2.p_sum - turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) - turning = (turning0 | turning1 | turning2) + turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + # Additional U turn check only when depth > 1 (to avoid redundant work). + if depth - 1 > 0: + p_sum1 = tree1.p_sum + tree2.left.p + turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) + p_sum2 = tree1.right.p + tree2.p_sum + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) + turning = (turning | turning1 | turning2) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): From 5ac16e31d78b27caeb13517bda911c2fcc307d2c Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 10:04:19 +0200 Subject: [PATCH 05/13] further logic to reduce redundant U Turn check. --- pymc3/step_methods/hmc/nuts.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index ff7c845b19..ba9fae3712 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -279,15 +279,18 @@ def extend(self, direction): self.log_size = np.logaddexp(self.log_size, tree.log_size) self.p_sum[:] += tree.p_sum - left, right = self.left, self.right - p_sum = self.p_sum - turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - p_sum1 = leftmost_p_sum + rightmost_begin.p - turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) - p_sum2 = leftmost_end.p + rightmost_p_sum - turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) + # Additional turning check only when tree depth > 0 to avoid redundant work + if self.depth > 0: + left, right = self.left, self.right + p_sum = self.p_sum + turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = leftmost_p_sum + rightmost_begin.p + turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) + p_sum2 = leftmost_end.p + rightmost_p_sum + turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) + turning = (turning | turning1 | turning2) - return diverging, (turning | turning1 | turning2) + return diverging, turning def _single_step(self, left, epsilon): """Perform a leapfrog step and handle error cases.""" @@ -336,7 +339,7 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - # Additional U turn check only when depth > 1 (to avoid redundant work). + # Additional U turn check only when depth > 1 to avoid redundant work. if depth - 1 > 0: p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) From 06af3a422eb665f59431a0bc80dab7c608ec545c Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Fri, 30 Aug 2019 08:50:02 +0200 Subject: [PATCH 06/13] bug fix fix error in recording the end point of the reversed subtree --- pymc3/step_methods/hmc/nuts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index ba9fae3712..6a83394e36 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -259,7 +259,7 @@ def extend(self, direction): else: tree, diverging, turning = self._build_subtree( self.left, self.depth, floatX(np.asarray(-self.step_size))) - leftmost_begin, leftmost_end = tree.left, tree.right + leftmost_begin, leftmost_end = tree.right, tree.left rightmost_begin, rightmost_end = self.left, self.right leftmost_p_sum = tree.p_sum rightmost_p_sum = self.p_sum From d0684a1eb196831dac5491c8f1f5209b00dd89cb Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sat, 24 Aug 2019 23:47:57 +0200 Subject: [PATCH 07/13] [WIP] Robust U-turn check Following the recent discussion on the Stan side: https://github.com/stan-dev/stan/pull/2800 For experiment, do not merge. --- pymc3/step_methods/hmc/nuts.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index 01e454fb6e..de2ff63318 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -251,10 +251,18 @@ def extend(self, direction): if direction > 0: tree, diverging, turning = self._build_subtree( self.right, self.depth, floatX(np.asarray(self.step_size))) + leftmost_begin, leftmost_end = self.left, self.right + rightmost_begin, rightmost_end = tree.left, tree.right + leftmost_p_sum = self.p_sum + rightmost_p_sum = tree.p_sum self.right = tree.right else: tree, diverging, turning = self._build_subtree( self.left, self.depth, floatX(np.asarray(-self.step_size))) + leftmost_begin, leftmost_end = tree.left, tree.right + rightmost_begin, rightmost_end = self.left, self.right + leftmost_p_sum = tree.p_sum + rightmost_p_sum = self.p_sum self.left = tree.right self.depth += 1 @@ -274,8 +282,12 @@ def extend(self, direction): left, right = self.left, self.right p_sum = self.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = leftmost_p_sum + rightmost_begin.p + turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) + p_sum2 = leftmost_end.p + rightmost_p_sum + turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) - return diverging, turning + return diverging, (turning | turning1 | turning2) def _single_step(self, left, epsilon): """Perform a leapfrog step and handle error cases.""" @@ -324,6 +336,10 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = tree1.p_sum + tree2.left.p + turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) + p_sum2 = tree1.right.p + tree2.p_sum + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.rigth.v) <= 0) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): @@ -340,7 +356,7 @@ def _build_subtree(self, left, depth, epsilon): tree = Subtree(left, right, p_sum, proposal, log_size, accept_sum, n_proposals) - return tree, diverging, turning + return tree, diverging, (turning | turning1 | turning2) def stats(self): return { From ea148efbee1d4ef4b1f5326eaf3e3c41f4ef0455 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 07:38:45 +0200 Subject: [PATCH 08/13] typo fix --- pymc3/step_methods/hmc/nuts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index de2ff63318..1a79047d20 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -339,7 +339,7 @@ def _build_subtree(self, left, depth, epsilon): p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) p_sum2 = tree1.right.p + tree2.p_sum - turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.rigth.v) <= 0) + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): From 6bba0b01db084550ac6f93b8141e3d3db99805e7 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 08:05:20 +0200 Subject: [PATCH 09/13] bug fix --- pymc3/step_methods/hmc/nuts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index 1a79047d20..e51f3dcd09 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -335,11 +335,12 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum - turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + turning0 = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) p_sum2 = tree1.right.p + tree2.p_sum turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) + turning = (turning0 | turning1 | turning2) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): @@ -356,7 +357,7 @@ def _build_subtree(self, left, depth, epsilon): tree = Subtree(left, right, p_sum, proposal, log_size, accept_sum, n_proposals) - return tree, diverging, (turning | turning1 | turning2) + return tree, diverging, turning def stats(self): return { From a5017d776979abdbca8669564f106a40a166076e Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 09:44:39 +0200 Subject: [PATCH 10/13] Additional U turn check only when depth > 1 (to avoid redundant work). --- pymc3/step_methods/hmc/nuts.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index e51f3dcd09..ff7c845b19 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -335,12 +335,14 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum - turning0 = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - p_sum1 = tree1.p_sum + tree2.left.p - turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) - p_sum2 = tree1.right.p + tree2.p_sum - turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) - turning = (turning0 | turning1 | turning2) + turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + # Additional U turn check only when depth > 1 (to avoid redundant work). + if depth - 1 > 0: + p_sum1 = tree1.p_sum + tree2.left.p + turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) + p_sum2 = tree1.right.p + tree2.p_sum + turning2 = (p_sum2.dot(tree1.right.v) <= 0) or (p_sum2.dot(tree2.right.v) <= 0) + turning = (turning | turning1 | turning2) log_size = np.logaddexp(tree1.log_size, tree2.log_size) if logbern(tree2.log_size - log_size): From 93673b1721d67fb1c4d1efea6fcc6837251ea469 Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Sun, 25 Aug 2019 10:04:19 +0200 Subject: [PATCH 11/13] further logic to reduce redundant U Turn check. --- pymc3/step_methods/hmc/nuts.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index ff7c845b19..ba9fae3712 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -279,15 +279,18 @@ def extend(self, direction): self.log_size = np.logaddexp(self.log_size, tree.log_size) self.p_sum[:] += tree.p_sum - left, right = self.left, self.right - p_sum = self.p_sum - turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - p_sum1 = leftmost_p_sum + rightmost_begin.p - turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) - p_sum2 = leftmost_end.p + rightmost_p_sum - turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) + # Additional turning check only when tree depth > 0 to avoid redundant work + if self.depth > 0: + left, right = self.left, self.right + p_sum = self.p_sum + turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) + p_sum1 = leftmost_p_sum + rightmost_begin.p + turning1 = (p_sum1.dot(leftmost_begin.v) <= 0) or (p_sum1.dot(rightmost_begin.v) <= 0) + p_sum2 = leftmost_end.p + rightmost_p_sum + turning2 = (p_sum2.dot(leftmost_end.v) <= 0) or (p_sum2.dot(rightmost_end.v) <= 0) + turning = (turning | turning1 | turning2) - return diverging, (turning | turning1 | turning2) + return diverging, turning def _single_step(self, left, epsilon): """Perform a leapfrog step and handle error cases.""" @@ -336,7 +339,7 @@ def _build_subtree(self, left, depth, epsilon): if not (diverging or turning): p_sum = tree1.p_sum + tree2.p_sum turning = (p_sum.dot(left.v) <= 0) or (p_sum.dot(right.v) <= 0) - # Additional U turn check only when depth > 1 (to avoid redundant work). + # Additional U turn check only when depth > 1 to avoid redundant work. if depth - 1 > 0: p_sum1 = tree1.p_sum + tree2.left.p turning1 = (p_sum1.dot(tree1.left.v) <= 0) or (p_sum1.dot(tree2.left.v) <= 0) From 699b1e8bf62eaa2db07af8f10e66bab87198c6bd Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Fri, 30 Aug 2019 08:50:02 +0200 Subject: [PATCH 12/13] bug fix fix error in recording the end point of the reversed subtree --- pymc3/step_methods/hmc/nuts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index ba9fae3712..6a83394e36 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -259,7 +259,7 @@ def extend(self, direction): else: tree, diverging, turning = self._build_subtree( self.left, self.depth, floatX(np.asarray(-self.step_size))) - leftmost_begin, leftmost_end = tree.left, tree.right + leftmost_begin, leftmost_end = tree.right, tree.left rightmost_begin, rightmost_end = self.left, self.right leftmost_p_sum = tree.p_sum rightmost_p_sum = self.p_sum From 281d5bc94f3374f635958d62e0653abf47f8ebcc Mon Sep 17 00:00:00 2001 From: Junpeng Lao Date: Thu, 17 Oct 2019 17:47:37 +0200 Subject: [PATCH 13/13] Add release note. --- RELEASE-NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index fb2b12fa18..3980f2c74b 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -3,6 +3,7 @@ ## PyMC3 3.8 (on deck) ### New features +- Implemented robust u turn check in NUTS (similar to stan-dev/stan#2800). See PR [#3605] - Add capabilities to do inference on parameters in a differential equation with `DifferentialEquation`. See [#3590](https://github.com/pymc-devs/pymc3/pull/3590). - Distinguish between `Data` and `Deterministic` variables when graphing models with graphviz. PR [#3491](https://github.com/pymc-devs/pymc3/pull/3491). - Sequential Monte Carlo - Approximate Bayesian Computation step method is now available. The implementation is in an experimental stage and will be further improved.