class_docstr: Lorenz System model.
  
  This class models the Lorenz System, a three-dimensional nonlinear dynamical
  system used to model atmospheric convection. This model defines a stochastic
  variant that follows the following differential equation:
  ```none
  x[0] ~ Normal(loc=0, scale=1)
  y[0] ~ Normal(loc=0, scale=1)
  z[0] ~ Normal(loc=0, scale=1)
  
  dx_dt[t] = 10 * (y[t] - x[t]) + w_x[t]
  dy_dt[t] = x[t] * (28 - z[t]) - y[t] + w_y[t]
  dz_dt[t] = x[t] * y[t] - 8 / 3 * z[t] + w_z[t]
  ```
  where `w_x[t]`, `w_y[t]` and `w_z[t]` are Gaussian innovation noise processes
  with a provided scale `innovation_scale`.
  
  The differential equation is numerically integrated using the Euler-Mariyama
  method whereafter the three time series `x`, `y`, and `z` (or a subset of
  them) are observed with Gaussian observation noise. Observations may be
  occluded with an `observation_mask` parameter.
docstr: Constructs a Lorenz System model.
  
  Args:
    observed_values: A `float` array of observed values whose first dimension
      corresponds to number of integration steps.
    innovation_scale: Python `float`, for the scale of the noise process in
      the Lorenz system dynamics.
    observation_scale: Python `float`, for the scale of the observation noise.
    observation_mask: Array of `bool` that occludes observed values.
    observation_index: Python `int` or `list` of `int`s that determines which
      latent time series are observed.
    step_size: Python `float` used for integrating the Lorenz dynamics.
    use_markov_chain: Python `bool` indicating whether to use the
      `MarkovChain` distribution in place of separate random variables for
      each time step. The default of `False` is for backwards compatibility;
      setting this to `True` should significantly improve performance.
    name: Python `str` name prefixed to Ops created by this class.
    pretty_name: A Python `str`. The pretty name of this model.
docstr_tok: ["Constructs","a","Lorenz","System","model",".","Args",":","observed_values",":","A","`","float","`","array","of","observed","values","whose","first","dimension","corresponds","to","number","of","integration","steps",".","innovation_scale",":","Python","`","float","`",",","for","the","scale","of","the","noise","process","in","the","Lorenz","system","dynamics",".","observation_scale",":","Python","`","float","`",",","for","the","scale","of","the","observation","noise",".","observation_mask",":","Array","of","`","bool","`","that","occludes","observed","values",".","observation_index",":","Python","`","int","`","or","`","list","`","of","`","int","`","s","that","determines","which","latent","time","series","are","observed",".","step_size",":","Python","`","float","`","used","for","integrating","the","Lorenz","dynamics",".","use_markov_chain",":","Python","`","bool","`","indicating","whether","to","use","the","`","MarkovChain","`","distribution","in","place","of","separate","random","variables","for","each","time","step",".","The","default","of","`","False","`","is","for","backwards","compatibility",";","setting","this","to","`","True","`","should","significantly","improve","performance",".","name",":","Python","`","str","`","name","prefixed","to","Ops","created","by","this","class",".","pretty_name",":","A","Python","`","str","`",".","The","pretty","name","of","this","model","."]
code: def __init__(
      self,
      observed_values,
      innovation_scale,
      observation_scale,
      observation_mask,
      observation_index,
      step_size,
      use_markov_chain=False,
      name="lorenz_system",
      pretty_name="Lorenz System",
  ):
      """Constructs a Lorenz System model.
  
      Args:
        observed_values: A `float` array of observed values whose first dimension
          corresponds to number of integration steps.
        innovation_scale: Python `float`, for the scale of the noise process in
          the Lorenz system dynamics.
        observation_scale: Python `float`, for the scale of the observation noise.
        observation_mask: Array of `bool` that occludes observed values.
        observation_index: Python `int` or `list` of `int`s that determines which
          latent time series are observed.
        step_size: Python `float` used for integrating the Lorenz dynamics.
        use_markov_chain: Python `bool` indicating whether to use the
          `MarkovChain` distribution in place of separate random variables for
          each time step. The default of `False` is for backwards compatibility;
          setting this to `True` should significantly improve performance.
        name: Python `str` name prefixed to Ops created by this class.
        pretty_name: A Python `str`. The pretty name of this model.
      """
      with tf.name_scope(name):
          dtype = dtype_util.common_dtype(
              [
                  observed_values,
                  innovation_scale,
                  observation_scale,
                  step_size,
              ],
              dtype_hint=tf.float32,
          )
          if not isinstance(observation_index, int):
              raise NotImplementedError(
                  "Observing multiple time series is not yet"
                  " supported."
              )
  
          num_timesteps = observed_values.shape[0]
  
          if use_markov_chain:
              self._prior_dist = lorenz_system_as_markov_chain(
                  num_timesteps=num_timesteps,
                  innovation_scale=innovation_scale,
                  step_size=step_size,
                  dtype=dtype,
              )
          else:
              self._prior_dist = tfd.JointDistributionCoroutine(
                  functools.partial(
                      lorenz_system_as_explicit_steps,
                      num_timesteps=num_timesteps,
                      innovation_scale=innovation_scale,
                      step_size=step_size,
                      dtype=dtype,
                  )
              )
  
          self._log_likelihood_fn = functools.partial(
              lorenz_system_log_likelihood_fn,
              observed_values=observed_values,
              observation_scale=observation_scale,
              observation_mask=observation_mask,
              observation_index=observation_index,
              use_markov_chain=use_markov_chain,
              dtype=dtype,
          )
  
          def _ext_identity(params):
              return params
  
          sample_transformations = {
              "identity": model.Model.SampleTransformation(
                  fn=_ext_identity,
                  pretty_name="Identity",
              )
          }
  
          event_space_bijector = (
              tfb.Identity()
              if use_markov_chain
              else type(self._prior_dist.dtype)(
                  *([tfb.Identity()] * num_timesteps)
              )
          )
      super(LorenzSystem, self).__init__(
          default_event_space_bijector=event_space_bijector,
          event_shape=self._prior_dist.event_shape,
          dtype=self._prior_dist.dtype,
          name=name,
          pretty_name=pretty_name,
          sample_transformations=sample_transformations,
      )
  
imports: import functools
  import numpy
  import tensorflow.compat.v2
  import tensorflow_probability
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import tensor_util
  from inference_gym.internal import data
  from inference_gym.targets import bayesian_model
  from inference_gym.targets import model
  from inference_gym.targets.ground_truth import convection_lorenz_bridge
  from inference_gym.targets.ground_truth import convection_lorenz_bridge_unknown_scales
label_desc: Use image node_id 1 to create a new LorenzSystem object from inherited base classes: bayesian_model with example: obj = LorenzSystem(observed_values, innovation_scale, observation_scale, observation_mask, observation_index, step_size, use_markov_chain, name, pretty_name)