コード例 #1
0
ファイル: deltatracking.py プロジェクト: DaWelter/ToyTrace
def weighted_delta_tracking_no_absorption(lambda_):
  """
    pg. 111:5, Algorithm 1. (rhs).
    Modified as per Sec. 5.1.3.
    Removal of volume absorption/emission events.
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  w = 1.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return (x, 0.)
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      ps = sigma_s / (sigma_s + abs(sigma_n))
      pn = abs(sigma_n) / (sigma_s + abs(sigma_n))
      r = random.uniform(0.,1.)
      if r < ps:
        w *= sigma_s / sigma_t_majorante_lambda / ps * ms.get_integrand(x)[lambda_]
        return (x, w)
      else:
        w *= sigma_n / sigma_t_majorante_lambda / pn
コード例 #2
0
ファイル: ratiotracking.py プロジェクト: DaWelter/ToyTrace
def ratio_tracking():
  """
    pg. 111:16, Eq (41)
  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight = np.ones(2, np.float32)
  while True:
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante
コード例 #3
0
ファイル: ratiotracking.py プロジェクト: DaWelter/ToyTrace
def single_lambda_ratio_tracking(lambda_):
  """
    pg. 111:16, Eq (41)
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  weight = 1.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante_lambda
コード例 #4
0
ファイル: ratiotracking.py プロジェクト: DaWelter/ToyTrace
def weighted_next_flight_estimator():
  """
    pg. 111:16, Eq (39)
    More variance than ratio tracking?!
  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight_product = np.ones(2, np.float32)
  weight = np.zeros(2, np.float32)
  while True:
    weight += np.exp(sigma_t_majorante * (x - ms.domain_length)) * weight_product
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight_product *= sigma_n / sigma_t_majorante
コード例 #5
0
ファイル: deltatracking.py プロジェクト: DaWelter/ToyTrace
def delta_tracking(lambda_):
  """
    pg. 111:5, Algorithm 1. (lhs). Although this is a very
    well known algorithm. Also known as woodcock tracking.
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return (x, 0.)
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      r = random.uniform(0.,1.)
      if r < (sigma_a / sigma_t_majorante_lambda):
        return (x, 0.)
      elif r < (1. - (sigma_n / sigma_t_majorante_lambda)):
        return (x, ms.get_integrand(x)[lambda_])
      else:
        pass # Null collision
コード例 #6
0
ファイル: deltatracking.py プロジェクト: DaWelter/ToyTrace
def spectral_tracking_no_absorption(x = 0, weights = None):
  """
    pg.  111:10, Algorithm 4.
    Modified as per Sec. 5.1.3.
    Removal of volume absorption/emission events.
  """
  weights = weights.copy() if weights is not None else np.ones(2, np.float32)
  while True:
    x += exp_sample(ms.sigma_t_majorante_across_channels)
    if x > ms.domain_length:
      return (x, weights)
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = ms.sigma_t_majorante_across_channels - sigma_s - sigma_a
      pt, pn = the_probability_scheme(weights, sigma_s, sigma_n)
      r = random.uniform(0.,1.)
      if r < pt:
        weights *= sigma_s / ms.sigma_t_majorante_across_channels * ms.get_integrand(x) / pt
        return (x, weights)
      else:
        weights *= sigma_n / ms.sigma_t_majorante_across_channels / pn
コード例 #7
0
ファイル: deltatracking.py プロジェクト: DaWelter/ToyTrace
def spectral_tracking():
  """
    pg.  111:10, Algorithm 4
  """
  weights = np.ones(2, np.float32)
  x = 0.
  while True:
    x += exp_sample(ms.sigma_t_majorante_across_channels)
    if x > ms.domain_length:
      return (x, weights)
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = ms.sigma_t_majorante_across_channels - sigma_s - sigma_a
      ps, pa, pn = the_probability_scheme(weights, sigma_s, sigma_a, sigma_n)
      r = random.uniform(0.,1.)
      if r < pa:
        return (x, np.zeros(2, np.float32))
      elif r < 1. - pn:
        weights *= sigma_s / ms.sigma_t_majorante_across_channels * ms.get_integrand(x) / ps
        return (x, weights)
      else:
        weights *= sigma_n / ms.sigma_t_majorante_across_channels / pn
コード例 #8
0
ファイル: ratiotracking.py プロジェクト: DaWelter/ToyTrace
def construct_piecewise_constant_transmittance():
  """
    By ratio tracking.
    We have positions xi, and associated weight wi. If we want to obtain
    an estimate of the transmittance of some point y, T(y) we look up
    the next xi which comes afterwards and use the estimate T^(y) = wi.
    In expectation T^(y) equals the true transmittance T(y).

  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight = np.ones(2, np.float32)
  points_and_weights = [c_(x, weight)]
  while True:
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      points_and_weights += [c_(x,weight)]
      break
    else:
      points_and_weights += [c_(x, weight)]
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante
      term_criterion = np.amax(weight)
      # Russian roulette termination. Otherwise I would have to traverse
      # through the entire domain which would be very inefficient if the
      # mean free path length is short
      r = random.uniform(0., 1.)
      survival_probability = term_criterion
      if r < survival_probability:  # live on
        weight /= survival_probability
      else:
        points_and_weights += [c_(ms.domain_length*1.1,np.zeros_like(weight))]
        break
  return np.asarray(points_and_weights)