class_docstr: Construct a Lorenz System model with unknown scale parameters.
  
  This class models a Lorenz System, a three-dimensional nonlinear dynamical
  system used to model atmospheric convection. The differential equation model
  is identical to that of `LorenzSystem`, which assumes fixed parameters, but
  here the scale parameters of the innovation and observation distributions are
  additionally modeled as unknown random variables:
  
  ```
  innovation_scale ~ LogNormal(-1., 1.)
  observation_scale ~ LogNormal(-1., 1.)
  
  # IID noise processes.
  w_x(t) ~ Normal(0., innovation_scale)
  w_y(t) ~ Normal(0., innovation_scale)
  w_z(t) ~ Normal(0., innovation_scale)
  
  x(0) ~ Normal(0, 1)
  y(0) ~ Normal(0, 1)
  z(0) ~ Normal(0, 1)
  
  x'(t) = 10 * (y(t) - x(t)) + w_x(t)
  y'(t) = x(t) * (28 - z(t)) - y(t) + w_y(t)
  z'(t) = x(t) * y(t) - 8 / 3 * z(t) + w_z(t)
  
  # Noisy observations.
  obs_x(t) ~ Normal(x(t), observation_scale)
  obs_y(t) ~ Normal(y(t), observation_scale)
  obs_z(t) ~ Normal(z(t), observation_scale)
  ```
docstr: Constructs a Lorenz System model.
  
  Args:
    observed_values: A `float` array of observed values whose first dimension
      corresponds to number of integration steps.
    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",".","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,
      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.
        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, 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]
  
          self._prior_dist = tfd.JointDistributionCoroutine(
              functools.partial(
                  lorenz_system_unknown_scales_prior_fn,
                  num_timesteps=num_timesteps,
                  step_size=step_size,
                  use_markov_chain=use_markov_chain,
                  dtype=dtype,
              )
          )
  
          self._log_likelihood_fn = functools.partial(
              lorenz_system_log_likelihood_fn,
              observed_values=observed_values,
              observation_scale=None,
              observation_mask=observation_mask,
              observation_index=observation_index,
              dtype=dtype,
              use_markov_chain=use_markov_chain,
          )
  
          def _ext_identity(params):
              return {
                  "innovation_scale": params[0],
                  "observation_scale": params[1],
                  "latents": (
                      params[2]
                      if use_markov_chain
                      else tf.stack(params[2:], -2)
                  ),
              }
  
          sample_transformations = {
              "identity": model.Model.SampleTransformation(
                  fn=_ext_identity,
                  pretty_name="Identity",
                  dtype={
                      "innovation_scale": tf.float32,
                      "observation_scale": tf.float32,
                      "latents": tf.float32,
                  },
              )
          }
  
          event_space_bijector = type(self._prior_dist.dtype)(
              *(
                  [tfb.Softplus(), tfb.Softplus()]
                  + [tfb.Identity()]
                  * (1 if use_markov_chain else num_timesteps)
              )
          )
      super(LorenzSystemUnknownScales, 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 LorenzSystemUnknownScales object from inherited base classes: bayesian_model with example: obj = LorenzSystemUnknownScales(observed_values, observation_mask, observation_index, step_size, use_markov_chain, name, pretty_name)