class_docstr: No-U-turn sampler (NUTS) on flat surfaces.
class_docstr_tok: ["No-U-turn","sampler","(","NUTS",")","on","flat","surfaces","."]
docstr: Build sub-trees of depth j in direction rwd
  
  startstate: (i, x, v) state information of first node
  j: int height of the tree
  rwd: bool whether we go backward
docstr_tok: ["Build","sub-trees","of","depth","j","in","direction","rwd","startstate",":","(","i",",","x",",","v",")","state","information","of","first","node","j",":","int","height","of","the","tree","rwd",":","bool","whether","we","go","backward"]
code: def build_tree(self, startstate, j, rwd):
      """
      Build sub-trees of depth j in direction rwd
  
      startstate: (i, x, v) state information of first node
      j: int height of the tree
      rwd: bool whether we go backward
      """
      if j == 0:
          # base case: go forward one step
          i = startstate[0] + (-1 if rwd else +1)
          # self.expand_to_step(i)
          # print("  build_tree@%d" % i, rwd, self.contourpath.samplingpath.fwd_possible, self.contourpath.samplingpath.rwd_possible)
          xi, vi, _, _ = self.contourpath.interpolate(i)
          if self.plot:
              plt.plot(xi[0], xi[1], "x", color="gray")
          # this is a good state, so return it
          return (i, xi, vi), (i, xi, vi), (i, i), False
  
      # recursion-build the left and right subtrees
      (
          (ileft, xleft, vleft),
          (iright, xright, vright),
          rangea,
          stopa,
      ) = self.build_tree(startstate, j - 1, rwd)
      if stopa:
          # print("  one subtree already terminated; returning")
          # plt.plot([xright[0], xleft[0]], [xright[1], xleft[1]], ':', color='navy')
          return (
              (ileft, xleft, vleft),
              (iright, xright, vright),
              (ileft, iright),
              stopa,
          )
      if rwd:
          # go back
          (ileft, xleft, vleft), _, rangeb, stopb = self.build_tree(
              (ileft, xleft, vleft), j - 1, rwd
          )
      else:
          _, (iright, xright, vright), rangeb, stopb = self.build_tree(
              (iright, xright, vright), j - 1, rwd
          )
      # print("  subtree termination at %d" % j, stopa, stopb, angle(xright-xleft, vleft), angle(xright-xleft, vright), angle(vleft, vright))
      # plt.plot([xright[0], xleft[0]], [xright[1], xleft[1]], ':', color='gray')
      # NUTS criterion: start to end vector must point in the same direction as velocity at end-point
      # additional criterion: start and end velocities must point in opposite directions
      stop = (
          stopa
          or stopb
          or angle(xright - xleft, vleft) <= 0
          or angle(xright - xleft, vright) <= 0
          or angle(vleft, vright) <= 0
      )
      return (
          (ileft, xleft, vleft),
          (iright, xright, vright),
          (ileft, iright),
          stop,
      )
  
imports: import numpy
  from numpy.linalg import norm
  import matplotlib.pyplot
  from .samplingpath import angle, extrapolate_ahead
label_desc: Use image node_id 4 for calling the ClockedNUTSSampler obj's underlying member method code with example usage: obj.build_tree(startstate, j, rwd) and returns: ileft,  xleft,  vleft,  iright,  xright,  vright,  ileft,  iright,  stop, i,  xi,  vi,  i,  xi,  vi,  i,  i,  False, ileft,  xleft,  vleft,  iright,  xright,  vright,  ileft,  iright,  stopa