class_docstr: Nested sampler with reactive exploration strategy.
  
  Storage & resume capable, optionally MPI parallelised.
class_docstr_tok: ["Nested","sampler","with","reactive","exploration","strategy",".","Storage","&","resume","capable",",","optionally","MPI","parallelised","."]
docstr: Build a new MLFriends region from `active_u`, and wrapping ellipsoid.
  
  Both are safely built using bootstrapping, so that the
  region can be used for sampling and rejecting points.
  If MPI is enabled, this computation is parallelised.
  
  If active_p is not None, a wrapping ellipsoid is built also
  in the user-transformed parameter space.
  
  Parameters
  -----------
  active_u: array of floats
      current live points
  active_node_ids: 2d array of ints
      which bootstrap initialisation the points belong to.
  active_rootids: 2d array of ints
      roots active in each bootstrap initialisation
  bootstrap_rootids: array of ints
      bootstrap samples. if None, they are drawn fresh.
  nbootstraps: int
      number of bootstrap rounds
  active_p: array of floats
      current live points, in user-transformed space
  minvol: float
      expected current minimum volume of region.
  
  Returns
  --------
  updated: bool
      True if update was made, False if previous region remained.
docstr_tok: ["Build","a","new","MLFriends","region","from","`","active_u","`",",","and","wrapping","ellipsoid",".","Both","are","safely","built","using","bootstrapping",",","so","that","the","region","can","be","used","for","sampling","and","rejecting","points",".","If","MPI","is","enabled",",","this","computation","is","parallelised",".","If","active_p","is","not","None",",","a","wrapping","ellipsoid","is","built","also","in","the","user-transformed","parameter","space",".","Parameters","--","--","--","--","--","-","active_u",":","array","of","floats","current","live","points","active_node_ids",":","2d","array","of","ints","which","bootstrap","initialisation","the","points","belong","to",".","active_rootids",":","2d","array","of","ints","roots","active","in","each","bootstrap","initialisation","bootstrap_rootids",":","array","of","ints","bootstrap","samples",".","if","None",",","they","are","drawn","fresh",".","nbootstraps",":","int","number","of","bootstrap","rounds","active_p",":","array","of","floats","current","live","points",",","in","user-transformed","space","minvol",":","float","expected","current","minimum","volume","of","region",".","Returns","--","--","--","--","updated",":","bool","True","if","update","was","made",",","False","if","previous","region","remained","."]
code: def _update_region(
      self,
      active_u,
      active_node_ids,
      bootstrap_rootids=None,
      active_rootids=None,
      nbootstraps=30,
      minvol=0.0,
      active_p=None,
  ):
      """Build a new MLFriends region from `active_u`, and wrapping ellipsoid.
  
      Both are safely built using bootstrapping, so that the
      region can be used for sampling and rejecting points.
      If MPI is enabled, this computation is parallelised.
  
      If active_p is not None, a wrapping ellipsoid is built also
      in the user-transformed parameter space.
  
      Parameters
      -----------
      active_u: array of floats
          current live points
      active_node_ids: 2d array of ints
          which bootstrap initialisation the points belong to.
      active_rootids: 2d array of ints
          roots active in each bootstrap initialisation
      bootstrap_rootids: array of ints
          bootstrap samples. if None, they are drawn fresh.
      nbootstraps: int
          number of bootstrap rounds
      active_p: array of floats
          current live points, in user-transformed space
      minvol: float
          expected current minimum volume of region.
  
      Returns
      --------
      updated: bool
          True if update was made, False if previous region remained.
  
      """
      assert nbootstraps > 0
      updated = False
      if self.region is None:
          # if self.log:
          #    self.logger.debug("building first region ...")
          self.transformLayer = self.transform_layer_class(
              wrapped_dims=self.wrapped_axes
          )
          self.transformLayer.optimize(
              active_u, active_u, minvol=minvol
          )
          self.region = self.region_class(active_u, self.transformLayer)
          self.region_nodes = active_node_ids.copy()
          assert self.region.maxradiussq is None
  
          _update_region_bootstrap(
              self.region,
              nbootstraps,
              minvol,
              self.comm if self.use_mpi else None,
              self.mpi_size,
          )
          self.region.create_ellipsoid(minvol=minvol)
          # if self.log:
          #     self.logger.debug("building first region ... r=%e, f=%e" % (r, f))
          updated = True
  
          # verify correctness:
          # self.region.create_ellipsoid(minvol=minvol)
          # assert self.region.inside(active_u).all(), self.region.inside(active_u).mean()
  
      assert self.transformLayer is not None
      need_accept = False
  
      if self.region.maxradiussq is None:
          # we have been told that radius is currently invalid
          # we need to bootstrap back to a valid state
  
          # compute radius given current transformLayer
          oldu = self.region.u
          self.region.u = active_u
          self.region_nodes = active_node_ids.copy()
          self.region.set_transformLayer(self.transformLayer)
  
          _update_region_bootstrap(
              self.region,
              nbootstraps,
              minvol,
              self.comm if self.use_mpi else None,
              self.mpi_size,
          )
  
          # print("made first region, r=%e" % (r))
  
          # now that we have r, can do clustering
          # but such reclustering would forget the cluster ids
  
          # instead, track the clusters from before by matching manually
          oldt = self.transformLayer.transform(oldu)
          clusterids = np.zeros(len(active_u), dtype=int)
          nnearby = np.empty(len(self.region.unormed), dtype=int)
          for ci in np.unique(self.transformLayer.clusterids):
              if ci == 0:
                  continue
  
              # find points from that cluster
              oldti = oldt[self.transformLayer.clusterids == ci]
              # identify which new points are near this cluster
              find_nearby(
                  oldti,
                  self.region.unormed,
                  self.region.maxradiussq,
                  nnearby,
              )
              mask = nnearby != 0
              # assign the nearby ones to this cluster
              # if they have not been set yet
              # if they have, set them to -1
              clusterids[mask] = np.where(clusterids[mask] == 0, ci, -1)
  
          # clusters we are unsure about (double assignments) go unassigned
          clusterids[clusterids == -1] = 0
  
          # tell scaling layer the correct cluster information
          self.transformLayer.clusterids = clusterids
  
          # we want the clustering to repeat to remove remaining zeros
          need_accept = (self.transformLayer.clusterids == 0).any()
  
          updated = True
          assert len(self.region.u) == len(
              self.transformLayer.clusterids
          )
  
          # verify correctness:
          self.region.create_ellipsoid(minvol=minvol)
          # assert self.region.inside(active_u).all(), self.region.inside(active_u).mean()
  
      assert len(self.region.u) == len(self.transformLayer.clusterids)
      # rebuild space
      with warnings.catch_warnings(), np.errstate(all="raise"):
          try:
              nextTransformLayer = self.transformLayer.create_new(
                  active_u, self.region.maxradiussq, minvol=minvol
              )
              assert not (nextTransformLayer.clusterids == 0).any()
              _, cluster_sizes = np.unique(
                  nextTransformLayer.clusterids, return_counts=True
              )
              smallest_cluster = cluster_sizes.min()
              if self.log and smallest_cluster == 1:
                  self.logger.debug(
                      "clustering found some stray points [need_accept=%s] %s",
                      need_accept,
                      np.unique(
                          nextTransformLayer.clusterids,
                          return_counts=True,
                      ),
                  )
  
              nextregion = self.region_class(
                  active_u, nextTransformLayer
              )
              assert np.isfinite(nextregion.unormed).all()
  
              if not nextTransformLayer.nclusters < 20:
                  if self.log:
                      self.logger.info(
                          "Found a lot of clusters: %d (%d with >1 members)",
                          nextTransformLayer.nclusters,
                          (cluster_sizes > 1).sum(),
                      )
  
              # if self.log:
              #     self.logger.info("computing maxradius...")
              r, f = _update_region_bootstrap(
                  nextregion,
                  nbootstraps,
                  minvol,
                  self.comm if self.use_mpi else None,
                  self.mpi_size,
              )
              # verify correctness:
              nextregion.create_ellipsoid(minvol=minvol)
  
              # check if live points are numerically colliding or linearly dependent
              self.live_points_healthy = (
                  len(active_u) > self.x_dim
                  and np.all(
                      np.sum(active_u[1:] != active_u[0], axis=0)
                      > self.x_dim
                  )
                  and np.linalg.matrix_rank(nextregion.ellipsoid_cov)
                  == self.x_dim
              )
  
              assert (nextregion.u == active_u).all()
              assert np.allclose(
                  nextregion.unormed,
                  nextregion.transformLayer.transform(active_u),
              )
              # assert nextregion.inside(active_u).all(),
              #  ("live points should live in new region, but only %.3f%% do." % (100 * nextregion.inside(active_u).mean()), active_u)
              good_region = nextregion.inside(active_u).all()
              # assert good_region
              if not good_region and self.log:
                  self.logger.debug(
                      "Proposed region is inconsistent (maxr=%g,enlarge=%g) and will be skipped.",
                      r,
                      f,
                  )
  
              # avoid cases where every point is its own cluster,
              # and even the largest cluster has fewer than x_dim points
              sensible_clustering = (
                  nextTransformLayer.nclusters < len(nextregion.u)
                  and cluster_sizes.max() >= nextregion.u.shape[1]
              )
  
              # force shrinkage of volume. avoids reconnecting dying modes
              if (
                  good_region
                  and (
                      need_accept
                      or nextregion.estimate_volume()
                      <= self.region.estimate_volume()
                  )
                  and sensible_clustering
              ):
                  self.region = nextregion
                  self.transformLayer = self.region.transformLayer
                  self.region_nodes = active_node_ids.copy()
                  updated = True
  
                  assert not (
                      self.transformLayer.clusterids == 0
                  ).any(), (
                      self.transformLayer.clusterids,
                      need_accept,
                      updated,
                  )
  
          except Warning:
              if self.log:
                  self.logger.debug(
                      "not updating region", exc_info=True
                  )
          except FloatingPointError:
              if self.log:
                  self.logger.debug(
                      "not updating region", exc_info=True
                  )
          except np.linalg.LinAlgError:
              if self.log:
                  self.logger.debug(
                      "not updating region", exc_info=True
                  )
  
      assert len(self.region.u) == len(self.transformLayer.clusterids)
  
      if active_p is None or not self.build_tregion:
          self.tregion = None
      else:
          try:
              with np.errstate(invalid="raise"):
                  tregion = WrappingEllipsoid(active_p)
                  f = tregion.compute_enlargement(
                      nbootstraps=max(1, nbootstraps // self.mpi_size)
                  )
                  if self.use_mpi:
                      recv_enlarge = self.comm.gather(f, root=0)
                      recv_enlarge = self.comm.bcast(
                          recv_enlarge, root=0
                      )
                      f = np.max(recv_enlarge)
                  tregion.enlarge = f
                  tregion.create_ellipsoid()
                  self.tregion = tregion
          except FloatingPointError:
              if self.log:
                  self.logger.debug(
                      "not updating t-ellipsoid", exc_info=True
                  )
                  self.tregion = None
          except np.linalg.LinAlgError:
              if self.log:
                  self.logger.debug(
                      "not updating t-ellipsoid", exc_info=True
                  )
                  self.tregion = None
  
      return updated
  
imports: from __future__ import print_function, division
  import os
  import sys
  import csv
  import json
  import operator
  import time
  import warnings
  from numpy import log, exp, logaddexp
  import numpy
  from .utils import create_logger, make_run_dir, resample_equal, vol_prefactor, vectorize, listify
  from .utils import is_affine_transform, normalised_kendall_tau_distance, distributed_work_chunk_size
  from ultranest.mlfriends import MLFriends, AffineLayer, ScalingLayer, find_nearby, WrappingEllipsoid, RobustEllipsoidRegion
  from .store import HDF5PointStore, TextPointStore, NullPointStore
  from .viz import get_default_viz_callback
  from .ordertest import UniformOrderAccumulator
  from .netiter import PointPile, SingleCounter, MultiCounter, BreadthFirstIterator, TreeNode, count_tree_between, find_nodes_before, logz_sequence
  from .netiter import dump_tree, combine_results
  from .hotstart import get_auxiliary_contbox_parameterization
label_desc: Use image node_id 12 for calling the ReactiveNestedSampler obj's underlying member method code with example usage: obj._update_region(active_u, active_node_ids, bootstrap_rootids, active_rootids, nbootstraps, minvol, active_p) and returns: updated