docstr: Args:
      x_dim:
      loglike:
      transform:
      prior:
      append_run_num:
      hidden_dim:
      num_slow:
      num_derived:
      batch_size:
      flow:
      num_blocks:
      num_layers:
      learning_rate:
      log_dir:
      resume:
      use_gpu:
      base_dist:
      scale:
      trainer:
      transform_prior:
      log_level:
      param_names:
docstr_tok: ["Args",":","x_dim",":","loglike",":","transform",":","prior",":","append_run_num",":","hidden_dim",":","num_slow",":","num_derived",":","batch_size",":","flow",":","num_blocks",":","num_layers",":","learning_rate",":","log_dir",":","resume",":","use_gpu",":","base_dist",":","scale",":","trainer",":","transform_prior",":","log_level",":","param_names",":"]
code: def __init__(
      self,
      x_dim,
      loglike,
      transform=None,
      prior=None,
      append_run_num=True,
      hidden_dim=16,
      num_slow=0,
      num_derived=0,
      batch_size=100,
      flow="spline",
      num_blocks=3,
      num_layers=1,
      learning_rate=0.001,
      log_dir="logs/test",
      resume=True,
      use_gpu=False,
      base_dist=None,
      scale="",
      trainer=None,
      transform_prior=True,
      oversample_rate=-1,
      log_level=logging.INFO,
      param_names=None,
  ):
      """
      Args:
          x_dim:
          loglike:
          transform:
          prior:
          append_run_num:
          hidden_dim:
          num_slow:
          num_derived:
          batch_size:
          flow:
          num_blocks:
          num_layers:
          learning_rate:
          log_dir:
          resume:
          use_gpu:
          base_dist:
          scale:
          trainer:
          transform_prior:
          log_level:
          param_names:
      """
  
      self.x_dim = x_dim
      self.num_derived = num_derived
      self.num_params = x_dim + num_derived
  
      assert x_dim > num_slow
      self.num_slow = num_slow
      self.num_fast = x_dim - num_slow
  
      self.param_names = param_names
      if self.param_names is not None:
          assert len(param_names) == self.num_params
  
      self.oversample_rate = (
          oversample_rate
          if oversample_rate > 0
          else self.num_fast / self.x_dim
      )
  
      if transform is None:
          self.transform = lambda x: x
      else:
  
          def safe_transform(x):
              if isinstance(x, list):
                  x = np.array(x)
              if len(x.shape) == 1:
                  assert x.shape[0] == self.x_dim
                  x = np.expand_dims(x, 0)
              return transform(x)
  
          self.transform = safe_transform
  
      def safe_loglike(x):
          if isinstance(x, list):
              x = np.array(x)
          if len(x.shape) == 1:
              assert x.shape[0] == self.x_dim
              x = np.expand_dims(x, 0)
          # Note the flow works in terms of rescaled coordinates. Transform back to the
          # original co-ordinates here to evaluate the likelihood
          res = loglike(self.transform(x))
          self.total_calls += x.shape[0]
          if isinstance(res, tuple):
              logl, derived = res
          else:
              logl = res
              # Set derived shape to be (batch size, 0)
              derived = np.array([[] for _ in x])
          if len(logl.shape) == 0:
              logl = np.expand_dims(logl, 0)
          logl[np.logical_not(np.isfinite(logl))] = -1e100
          if len(derived.shape) == 1:
              raise ValueError(
                  "Derived should have dimensions (batch size, num derived params)"
              )
          if derived.shape[1] != self.num_derived:
              raise ValueError(
                  "Is the number of derived parameters correct?"
              )
          return logl, derived
  
      self.loglike = safe_loglike
  
      sample_prior = getattr(prior, "sample", None)
      if callable(sample_prior):
          self.sample_prior = sample_prior
      else:
          self.sample_prior = None
  
      if prior is None:
  
          def safe_prior(x):
              if isinstance(x, list):
                  x = np.array(x)
              if len(x.shape) == 1:
                  assert x.shape[0] == self.x_dim
                  x = np.expand_dims(x, 0)
              return np.array([0 for x in x])
  
      else:
  
          def safe_prior(x):
              if isinstance(x, list):
                  x = np.array(x)
              if len(x.shape) == 1:
                  assert x.shape[0] == self.x_dim
                  x = np.expand_dims(x, 0)
              if transform_prior:
                  return np.array([prior(self.transform(x)) for x in x])
              else:
                  return np.array([prior(x) for x in x])
  
      self.prior = safe_prior
  
      self.use_mpi = False
      try:
          from mpi4py import MPI
  
          self.comm = MPI.COMM_WORLD
          self.mpi_size = self.comm.Get_size()
          self.mpi_rank = self.comm.Get_rank()
          if self.mpi_size > 1:
              self.use_mpi = True
      except:
          self.mpi_size = 1
          self.mpi_rank = 0
  
      self.single_or_primary_process = not self.use_mpi or (
          self.use_mpi and self.mpi_rank == 0
      )
  
      args = locals()
      args.update(vars(self))
  
      if self.single_or_primary_process or os.path.isdir(
          os.path.join(log_dir, "info")
      ):
          self.logs = get_or_create_run_dir(
              log_dir, append_run_num=append_run_num
          )
          self.log_dir = self.logs["run_dir"]
      else:
          self.logs = None
          self.log_dir = None
  
      if self.single_or_primary_process:
          self._save_params(args)
  
      self.resume = resume
  
      self.logger = create_logger(__name__, level=log_level)
  
      if trainer is None:
          self.trainer = Trainer(
              x_dim,
              hidden_dim=hidden_dim,
              num_slow=num_slow,
              batch_size=batch_size,
              flow=flow,
              num_blocks=num_blocks,
              num_layers=num_layers,
              learning_rate=learning_rate,
              log_dir=self.log_dir,
              log=self.single_or_primary_process,
              use_gpu=use_gpu,
              base_dist=base_dist,
              scale=scale,
          )
      else:
          self.trainer = trainer
  
      if self.single_or_primary_process:
          self.logger.info("Num base params [%d]" % (self.x_dim))
          self.logger.info(
              "Num derived params [%d]" % (self.num_derived)
          )
          self.logger.info("Total params [%d]" % (self.num_params))
  
      self.total_accepted = 0
      self.total_rejected = 0
      self.total_calls = 0
      self.total_fast_calls = 0
  
imports: from __future__ import print_function
  from __future__ import division
  import os
  import json
  import logging
  import time
  import torch
  import numpy
  from tqdm import tqdm
  import matplotlib.pyplot
  from nnest.trainer import Trainer
  from nnest.utils.evaluation import acceptance_rate, effective_sample_size, mean_jump_distance, gelman_rubin_diagnostic
  from nnest.utils.logger import create_logger, get_or_create_run_dir
label_desc: Use image node_id 1 to create a new Sampler object from inherited base classes: object with example: obj = Sampler(x_dim, loglike, transform, prior, append_run_num, hidden_dim, num_slow, num_derived, batch_size, flow, num_blocks, num_layers, learning_rate, log_dir, resume, use_gpu, base_dist, scale, trainer, transform_prior, oversample_rate, log_level, param_names)