class_docstr: Dynamic Hamiltonian/Hybrid Monte Carlo technique
  
  Typically, HMC operates on the posterior. It has the benefit
  of producing "orbit" trajectories, that can follow the guidance
  of gradients.
  
  In nested sampling, we need to sample the prior subject to the
  likelihood constraint. This means a HMC would most of the time
  go in straight lines, until it steps outside the boundary.
  Techniques such as Constrained HMC and Galilean MC use the
  gradient outside to select the reflection direction.
  
  However, it would be beneficial to be repelled by the likelihood
  boundary, and to take advantage of gradient guidance.
  This implements a new technique that does this.
  
  The trick is to define a auxiliary distribution from the likelihood,
  generate HMC trajectories from it, and draw points from the
  trajectory with inverse the probability of the auxiliary distribution
  to sample from the prior. Thus, the auxiliary distribution should be
  mostly flat, and go to zero at the boundaries to repell the HMC.
  
  Given Lmin and Lmax from the live points,
  use a beta approximation of log-likelihood
  
  p=1 if L>Lmin
  u = (L - Lmin) / (Lmax - Lmin)
  p = Beta_PDF(u; alpha, beta)
  
  then define
   d log(p) / dx = dlog(p_orig)/dlog(p) * dlog(p_orig) / dx
   new gradient  = conversion           * original gradient
  
  with conversion
   dlogp/du = 0 if u>1; otherwise:
   dlogp/du =  u**(1-alpha) * (1-u)**(1-beta) / Ic(u; alpha, beta) / Beta_PDF(u, alpha, beta)
   du/dL = 1 / (Lmax - Lmin)
  
  The beta distribution achieves:
  * a flattening of the loglikelihood to avoid seeing only "walls"
  * using the gradient to identify how to orbit the likelihood contour
  * at higher, unseen likelihoods, the exploration is in straight lines
  * trajectory do not have the energy to go below Lmin.
  * alpha and beta parameters allow flexible choice of "contour avoidance"
  
  Run HMC trajectory on p
  This will draw samples proportional to p
  Modify multinomial acceptance by 1/p to get uniform samples.
  and  reject porig < p_1
  
  The remaining choices for HMC are how long the trajectories should
  run (number of steps) and the step size. The former is solved
  by No-U-Turn Sampler or dynamic HMC, which randomly build
  forward and backward paths until the trajectory turns around.
  Then, a random point from the trajectory is chosen.
  
  The step size is chosen by targeting an acceptance rate of
  delta~0.95, and decreasing(increasing) every time the region is
  rebuilt if the acceptance rate is below(above).
class_docstr_tok: ["Dynamic","Hamiltonian\/Hybrid","Monte","Carlo","technique","Typically",",","HMC","operates","on","the","posterior",".","It","has","the","benefit","of","producing","``","orbit","''","trajectories",",","that","can","follow","the","guidance","of","gradients",".","In","nested","sampling",",","we","need","to","sample","the","prior","subject","to","the","likelihood","constraint",".","This","means","a","HMC","would","most","of","the","time","go","in","straight","lines",",","until","it","steps","outside","the","boundary",".","Techniques","such","as","Constrained","HMC","and","Galilean","MC","use","the","gradient","outside","to","select","the","reflection","direction",".","However",",","it","would","be","beneficial","to","be","repelled","by","the","likelihood","boundary",",","and","to","take","advantage","of","gradient","guidance",".","This","implements","a","new","technique","that","does","this",".","The","trick","is","to","define","a","auxiliary","distribution","from","the","likelihood",",","generate","HMC","trajectories","from","it",",","and","draw","points","from","the","trajectory","with","inverse","the","probability","of","the","auxiliary","distribution","to","sample","from","the","prior",".","Thus",",","the","auxiliary","distribution","should","be","mostly","flat",",","and","go","to","zero","at","the","boundaries","to","repell","the","HMC",".","Given","Lmin","and","Lmax","from","the","live","points",",","use","a","beta","approximation","of","log-likelihood","p=1","if","L",">","Lmin","u","=","(","L","-","Lmin",")","\/","(","Lmax","-","Lmin",")","p","=","Beta_PDF","(","u",";","alpha",",","beta",")","then","define","d","log","(","p",")","\/","dx","=","dlog","(","p_orig",")","\/dlog","(","p",")","*","dlog","(","p_orig",")","\/","dx","new","gradient","=","conversion","*","original","gradient","with","conversion","dlogp\/du","=","0","if","u",">","1",";","otherwise",":","dlogp\/du","=","u","*","*","(","1-alpha",")","*","(","1-u",")","*","*","(","1-beta",")","\/","Ic","(","u",";","alpha",",","beta",")","\/","Beta_PDF","(","u",",","alpha",",","beta",")","du\/dL","=","1","\/","(","Lmax","-","Lmin",")","The","beta","distribution","achieves",":","*","a","flattening","of","the","loglikelihood","to","avoid","seeing","only","``","walls","''","*","using","the","gradient","to","identify","how","to","orbit","the","likelihood","contour","*","at","higher",",","unseen","likelihoods",",","the","exploration","is","in","straight","lines","*","trajectory","do","not","have","the","energy","to","go","below","Lmin",".","*","alpha","and","beta","parameters","allow","flexible","choice","of","``","contour","avoidance","''","Run","HMC","trajectory","on","p","This","will","draw","samples","proportional","to","p","Modify","multinomial","acceptance","by","1\/p","to","get","uniform","samples",".","and","reject","porig","<","p_1","The","remaining","choices","for","HMC","are","how","long","the","trajectories","should","run","(","number","of","steps",")","and","the","step","size",".","The","former","is","solved","by","No-U-Turn","Sampler","or","dynamic","HMC",",","which","randomly","build","forward","and","backward","paths","until","the","trajectory","turns","around",".","Then",",","a","random","point","from","the","trajectory","is","chosen",".","The","step","size","is","chosen","by","targeting","an","acceptance","rate","of","delta~0.95",",","and","decreasing","(","increasing",")","every","time","the","region","is","rebuilt","if","the","acceptance","rate","is","below","(","above",")","."]
docstr: Get a new point.
  
  Parameters
  ----------
  region: MLFriends
      region.
  Lmin: float
      loglikelihood threshold
  us: array of vectors
      current live points
  Ls: array of floats
      current live point likelihoods
  transform: function
      transform function
  loglike: function
      loglikelihood function
  ndraw: int
      number of draws to attempt simultaneously.
  plot: bool
      whether to produce debug plots.
docstr_tok: ["Get","a","new","point",".","Parameters","--","--","--","--","--","region",":","MLFriends","region",".","Lmin",":","float","loglikelihood","threshold","us",":","array","of","vectors","current","live","points","Ls",":","array","of","floats","current","live","point","likelihoods","transform",":","function","transform","function","loglike",":","function","loglikelihood","function","ndraw",":","int","number","of","draws","to","attempt","simultaneously",".","plot",":","bool","whether","to","produce","debug","plots","."]
code: def __next__(
      self,
      region,
      Lmin,
      us,
      Ls,
      transform,
      loglike,
      ndraw=40,
      plot=False,
  ):
      """Get a new point.
  
      Parameters
      ----------
      region: MLFriends
          region.
      Lmin: float
          loglikelihood threshold
      us: array of vectors
          current live points
      Ls: array of floats
          current live point likelihoods
      transform: function
          transform function
      loglike: function
          loglikelihood function
      ndraw: int
          number of draws to attempt simultaneously.
      plot: bool
          whether to produce debug plots.
  
      """
      # i = np.argsort(Ls)[0]
      mask = Ls > Lmin
      i = np.random.randint(mask.sum())
      # print("starting from live point %d" % i)
      self.starti = np.where(mask)[0][i]
      ui = us[mask, :][i]
      assert np.logical_and(ui > 0, ui < 1).all(), ui
  
      if self.problem is None:
          self.create_problem(Ls, region)
  
      ncalls_total = 1
      (Lflat, gradflat), (pi, Li, gradi) = self.problem(ui)
      assert np.shape(Lflat) == (), (Lflat, Li, gradi)
      assert np.shape(gradflat) == (len(ui),), (gradi, gradflat)
  
      nsteps_remaining = self.nsteps
      while nsteps_remaining > 0:
          (
              unew,
              pnew,
              Lnew,
              gradnew,
              Lflatnew,
              gradflatnew,
              nc,
              alpha,
              beta,
              treeheight,
          ) = self.move(
              ui,
              pi,
              Li,
              gradi,
              gradflat=gradflat,
              Lflat=Lflat,
              region=region,
              ndraw=ndraw,
              plot=plot,
          )
  
          if treeheight > 1:
              # do not count failed accepts
              nsteps_remaining = nsteps_remaining - 1
          else:
              print("stuck:", Li, "->", Lnew, "Lmin:", Lmin)
  
          ncalls_total += nc
          # print(" ->", Li, Lnew, unew)
          assert np.logical_and(unew > 0, unew < 1).all(), unew
  
          if plot:
              plt.plot(
                  [ui[0], unew[:, 0]],
                  [ui[1], unew[:, 1]],
                  "-",
                  color="k",
                  lw=0.5,
              )
              plt.plot(ui[0], ui[1], "d", color="r", ms=4)
              plt.plot(unew[:, 0], unew[:, 1], "x", color="r", ms=4)
  
          ui, pi, Li, gradi, Lflat, gradflat = (
              unew,
              pnew,
              Lnew,
              gradnew,
              Lflatnew,
              gradflatnew,
          )
  
          self.logstat_trajectory.append([alpha, beta, treeheight])
  
      self.adjust_stepsize()
  
      return unew, pnew, Lnew, nc
  
imports: import numpy
  import matplotlib.pyplot
  import scipy.special
  import scipy.stats
label_desc: Use image node_id 4 for calling the DynamicHMCSampler obj's underlying member method code with example usage: obj.__next__(region, Lmin, us, Ls, transform, loglike, ndraw, plot) and returns: unew,  pnew,  Lnew,  nc