class_docstr: Formal representation of a seasonal effect model.
  
  A seasonal effect model posits a fixed set of recurring, discrete 'seasons',
  each of which is active for a fixed number of timesteps and, while active,
  contributes a different effect to the time series. These are generally not
  meteorological seasons, but represent regular recurring patterns such as
  hour-of-day or day-of-week effects. Each season lasts for a fixed number of
  timesteps. The effect of each season drifts from one occurrence to the next
  following a Gaussian random walk:
  
  ```python
  effects[season, occurrence[i]] = (
    effects[season, occurrence[i-1]] + Normal(loc=0., scale=drift_scale))
  ```
  
  The `drift_scale` parameter governs the standard deviation of the random walk;
  for example, in a day-of-week model it governs the change in effect from this
  Monday to next Monday.
  
  #### Examples
  
  A seasonal effect model representing day-of-week seasonality on hourly data:
  
  ```python
  day_of_week = tfp.sts.Seasonal(num_seasons=7,
                                 num_steps_per_season=24,
                                 observed_time_series=y,
                                 name='day_of_week')
  ```
  
  A seasonal effect model representing month-of-year seasonality on daily data,
  with explicit priors:
  
  ```python
  month_of_year = tfp.sts.Seasonal(
    num_seasons=12,
    num_steps_per_season=[31, 28, 31, 30, 30, 31, 31, 31, 30, 31, 30, 31],
    drift_scale_prior=tfd.LogNormal(loc=-1., scale=0.1),
    initial_effect_prior=tfd.Normal(loc=0., scale=5.),
    name='month_of_year')
  ```
  
  Note that this version works over time periods not involving a leap year. A
  general implementation of month-of-year seasonality would require additional
  logic:
  
  ```python
  num_days_per_month = np.array(
    [[31, 28, 31, 30, 30, 31, 31, 31, 30, 31, 30, 31],
     [31, 29, 31, 30, 30, 31, 31, 31, 30, 31, 30, 31],  # year with leap day
     [31, 28, 31, 30, 30, 31, 31, 31, 30, 31, 30, 31],
     [31, 28, 31, 30, 30, 31, 31, 31, 30, 31, 30, 31]])
  
  month_of_year = tfp.sts.Seasonal(
    num_seasons=12,
    num_steps_per_season=num_days_per_month,
    drift_scale_prior=tfd.LogNormal(loc=-1., scale=0.1),
    initial_effect_prior=tfd.Normal(loc=0., scale=5.),
    name='month_of_year')
  ```
  
  A model representing both day-of-week and hour-of-day seasonality, on hourly
  data:
  
  ```
  day_of_week = tfp.sts.Seasonal(num_seasons=7,
                                 num_steps_per_season=24,
                                 observed_time_series=y,
                                 name='day_of_week')
  hour_of_day = tfp.sts.Seasonal(num_seasons=24,
                                 num_steps_per_season=1,
                                 observed_time_series=y,
                                 name='hour_of_day')
  model = tfp.sts.Sum(components=[day_of_week, hour_of_day],
                      observed_time_series=y)
  ```
class_docstr_tok: ["Formal","representation","of","a","seasonal","effect","model",".","A","seasonal","effect","model","posits","a","fixed","set","of","recurring",",","discrete","'seasons","'",",","each","of","which","is","active","for","a","fixed","number","of","timesteps","and",",","while","active",",","contributes","a","different","effect","to","the","time","series",".","These","are","generally","not","meteorological","seasons",",","but","represent","regular","recurring","patterns","such","as","hour-of-day","or","day-of-week","effects",".","Each","season","lasts","for","a","fixed","number","of","timesteps",".","The","effect","of","each","season","drifts","from","one","occurrence","to","the","next","following","a","Gaussian","random","walk",":","``","`","python","effects","[","season",",","occurrence","[","i","]","]","=","(","effects","[","season",",","occurrence","[","i-1","]","]","+","Normal","(","loc=0.",",","scale=drift_scale",")",")","``","`","The","`","drift_scale","`","parameter","governs","the","standard","deviation","of","the","random","walk",";","for","example",",","in","a","day-of-week","model","it","governs","the","change","in","effect","from","this","Monday","to","next","Monday",".","#","#","#","#","Examples","A","seasonal","effect","model","representing","day-of-week","seasonality","on","hourly","data",":","``","`","python","day_of_week","=","tfp.sts.Seasonal","(","num_seasons=7",",","num_steps_per_season=24",",","observed_time_series=y",",","name='day_of_week","'",")","``","`","A","seasonal","effect","model","representing","month-of-year","seasonality","on","daily","data",",","with","explicit","priors",":","``","`","python","month_of_year","=","tfp.sts.Seasonal","(","num_seasons=12",",","num_steps_per_season=","[","31",",","28",",","31",",","30",",","30",",","31",",","31",",","31",",","30",",","31",",","30",",","31","]",",","drift_scale_prior=tfd.LogNormal","(","loc=-1.",",","scale=0.1",")",",","initial_effect_prior=tfd.Normal","(","loc=0.",",","scale=5",".",")",",","name='month_of_year","'",")","``","`","Note","that","this","version","works","over","time","periods","not","involving","a","leap","year",".","A","general","implementation","of","month-of-year","seasonality","would","require","additional","logic",":","``","`","python","num_days_per_month","=","np.array","(","[","[","31",",","28",",","31",",","30",",","30",",","31",",","31",",","31",",","30",",","31",",","30",",","31","]",",","[","31",",","29",",","31",",","30",",","30",",","31",",","31",",","31",",","30",",","31",",","30",",","31","]",",","#","year","with","leap","day","[","31",",","28",",","31",",","30",",","30",",","31",",","31",",","31",",","30",",","31",",","30",",","31","]",",","[","31",",","28",",","31",",","30",",","30",",","31",",","31",",","31",",","30",",","31",",","30",",","31","]","]",")","month_of_year","=","tfp.sts.Seasonal","(","num_seasons=12",",","num_steps_per_season=num_days_per_month",",","drift_scale_prior=tfd.LogNormal","(","loc=-1.",",","scale=0.1",")",",","initial_effect_prior=tfd.Normal","(","loc=0.",",","scale=5",".",")",",","name='month_of_year","'",")","``","`","A","model","representing","both","day-of-week","and","hour-of-day","seasonality",",","on","hourly","data",":","``","`","day_of_week","=","tfp.sts.Seasonal","(","num_seasons=7",",","num_steps_per_season=24",",","observed_time_series=y",",","name='day_of_week","'",")","hour_of_day","=","tfp.sts.Seasonal","(","num_seasons=24",",","num_steps_per_season=1",",","observed_time_series=y",",","name='hour_of_day","'",")","model","=","tfp.sts.Sum","(","components=","[","day_of_week",",","hour_of_day","]",",","observed_time_series=y",")","``","`"]
docstr: Specify a seasonal effects model.
  
  Args:
    num_seasons: Scalar Python `int` number of seasons.
    num_steps_per_season: Python `int` number of steps in each
      season. This may be either a scalar (shape `[]`), in which case all
      seasons have the same length, or a NumPy array of shape `[num_seasons]`,
      in which seasons have different length, but remain constant around
      different cycles, or a NumPy array of shape `[num_cycles, num_seasons]`,
      in which num_steps_per_season for each season also varies in different
      cycle (e.g., a 4 years cycle with leap day).
      Default value: 1.
    allow_drift: optional Python `bool` specifying whether the seasonal
      effects can drift over time.  Setting this to `False`
      removes the `drift_scale` parameter from the model. This is
      mathematically equivalent to
      `drift_scale_prior = tfd.Deterministic(0.)`, but removing drift
      directly is preferred because it avoids the use of a degenerate prior.
      Default value: `True`.
    drift_scale_prior: optional `tfd.Distribution` instance specifying a prior
      on the `drift_scale` parameter. If `None`, a heuristic default prior is
      constructed based on the provided `observed_time_series`.
      Default value: `None`.
    initial_effect_prior: optional `tfd.Distribution` instance specifying a
      normal prior on the initial effect of each season. This may be either
      a scalar `tfd.Normal` prior, in which case it applies independently to
      every season, or it may be multivariate normal (e.g.,
      `tfd.MultivariateNormalDiag`) with event shape `[num_seasons]`, in
      which case it specifies a joint prior across all seasons. If `None`, a
      heuristic default prior is constructed based on the provided
      `observed_time_series`.
      Default value: `None`.
    constrain_mean_effect_to_zero: if `True`, use a model parameterization
      that constrains the mean effect across all seasons to be zero. This
      constraint is generally helpful in identifying the contributions of
      different model components and can lead to more interpretable
      posterior decompositions. It may be undesirable if you plan to directly
      examine the latent space of the underlying state space model.
      Default value: `True`.
    observed_time_series: optional `float` `Tensor` of shape
      `batch_shape + [T, 1]` (omitting the trailing unit dimension is also
      supported when `T > 1`), specifying an observed time series. Any `NaN`s
      are interpreted as missing observations; missingness may be also be
      explicitly specified by passing a `tfp.sts.MaskedTimeSeries` instance.
      Any priors not explicitly set will be given default values according to
      the scale of the observed time series (or batch of time series).
      Default value: `None`.
    name: the name of this model component.
      Default value: 'Seasonal'.
docstr_tok: ["Specify","a","seasonal","effects","model",".","Args",":","num_seasons",":","Scalar","Python","`","int","`","number","of","seasons",".","num_steps_per_season",":","Python","`","int","`","number","of","steps","in","each","season",".","This","may","be","either","a","scalar","(","shape","`","[","]","`",")",",","in","which","case","all","seasons","have","the","same","length",",","or","a","NumPy","array","of","shape","`","[","num_seasons","]","`",",","in","which","seasons","have","different","length",",","but","remain","constant","around","different","cycles",",","or","a","NumPy","array","of","shape","`","[","num_cycles",",","num_seasons","]","`",",","in","which","num_steps_per_season","for","each","season","also","varies","in","different","cycle","(","e.g.",",","a","4","years","cycle","with","leap","day",")",".","Default","value",":","1.","allow_drift",":","optional","Python","`","bool","`","specifying","whether","the","seasonal","effects","can","drift","over","time",".","Setting","this","to","`","False","`","removes","the","`","drift_scale","`","parameter","from","the","model",".","This","is","mathematically","equivalent","to","`","drift_scale_prior","=","tfd.Deterministic","(","0",".",")","`",",","but","removing","drift","directly","is","preferred","because","it","avoids","the","use","of","a","degenerate","prior",".","Default","value",":","`","True","`",".","drift_scale_prior",":","optional","`","tfd.Distribution","`","instance","specifying","a","prior","on","the","`","drift_scale","`","parameter",".","If","`","None","`",",","a","heuristic","default","prior","is","constructed","based","on","the","provided","`","observed_time_series","`",".","Default","value",":","`","None","`",".","initial_effect_prior",":","optional","`","tfd.Distribution","`","instance","specifying","a","normal","prior","on","the","initial","effect","of","each","season",".","This","may","be","either","a","scalar","`","tfd.Normal","`","prior",",","in","which","case","it","applies","independently","to","every","season",",","or","it","may","be","multivariate","normal","(","e.g.",",","`","tfd.MultivariateNormalDiag","`",")","with","event","shape","`","[","num_seasons","]","`",",","in","which","case","it","specifies","a","joint","prior","across","all","seasons",".","If","`","None","`",",","a","heuristic","default","prior","is","constructed","based","on","the","provided","`","observed_time_series","`",".","Default","value",":","`","None","`",".","constrain_mean_effect_to_zero",":","if","`","True","`",",","use","a","model","parameterization","that","constrains","the","mean","effect","across","all","seasons","to","be","zero",".","This","constraint","is","generally","helpful","in","identifying","the","contributions","of","different","model","components","and","can","lead","to","more","interpretable","posterior","decompositions",".","It","may","be","undesirable","if","you","plan","to","directly","examine","the","latent","space","of","the","underlying","state","space","model",".","Default","value",":","`","True","`",".","observed_time_series",":","optional","`","float","`","`","Tensor","`","of","shape","`","batch_shape","+","[","T",",","1","]","`","(","omitting","the","trailing","unit","dimension","is","also","supported","when","`","T",">","1","`",")",",","specifying","an","observed","time","series",".","Any","`","NaN","`","s","are","interpreted","as","missing","observations",";","missingness","may","be","also","be","explicitly","specified","by","passing","a","`","tfp.sts.MaskedTimeSeries","`","instance",".","Any","priors","not","explicitly","set","will","be","given","default","values","according","to","the","scale","of","the","observed","time","series","(","or","batch","of","time","series",")",".","Default","value",":","`","None","`",".","name",":","the","name","of","this","model","component",".","Default","value",":","'Seasonal","'","."]
code: def __init__(
      self,
      num_seasons,
      num_steps_per_season=1,
      allow_drift=True,
      drift_scale_prior=None,
      initial_effect_prior=None,
      constrain_mean_effect_to_zero=True,
      observed_time_series=None,
      name=None,
  ):
      """Specify a seasonal effects model.
  
      Args:
        num_seasons: Scalar Python `int` number of seasons.
        num_steps_per_season: Python `int` number of steps in each
          season. This may be either a scalar (shape `[]`), in which case all
          seasons have the same length, or a NumPy array of shape `[num_seasons]`,
          in which seasons have different length, but remain constant around
          different cycles, or a NumPy array of shape `[num_cycles, num_seasons]`,
          in which num_steps_per_season for each season also varies in different
          cycle (e.g., a 4 years cycle with leap day).
          Default value: 1.
        allow_drift: optional Python `bool` specifying whether the seasonal
          effects can drift over time.  Setting this to `False`
          removes the `drift_scale` parameter from the model. This is
          mathematically equivalent to
          `drift_scale_prior = tfd.Deterministic(0.)`, but removing drift
          directly is preferred because it avoids the use of a degenerate prior.
          Default value: `True`.
        drift_scale_prior: optional `tfd.Distribution` instance specifying a prior
          on the `drift_scale` parameter. If `None`, a heuristic default prior is
          constructed based on the provided `observed_time_series`.
          Default value: `None`.
        initial_effect_prior: optional `tfd.Distribution` instance specifying a
          normal prior on the initial effect of each season. This may be either
          a scalar `tfd.Normal` prior, in which case it applies independently to
          every season, or it may be multivariate normal (e.g.,
          `tfd.MultivariateNormalDiag`) with event shape `[num_seasons]`, in
          which case it specifies a joint prior across all seasons. If `None`, a
          heuristic default prior is constructed based on the provided
          `observed_time_series`.
          Default value: `None`.
        constrain_mean_effect_to_zero: if `True`, use a model parameterization
          that constrains the mean effect across all seasons to be zero. This
          constraint is generally helpful in identifying the contributions of
          different model components and can lead to more interpretable
          posterior decompositions. It may be undesirable if you plan to directly
          examine the latent space of the underlying state space model.
          Default value: `True`.
        observed_time_series: optional `float` `Tensor` of shape
          `batch_shape + [T, 1]` (omitting the trailing unit dimension is also
          supported when `T > 1`), specifying an observed time series. Any `NaN`s
          are interpreted as missing observations; missingness may be also be
          explicitly specified by passing a `tfp.sts.MaskedTimeSeries` instance.
          Any priors not explicitly set will be given default values according to
          the scale of the observed time series (or batch of time series).
          Default value: `None`.
        name: the name of this model component.
          Default value: 'Seasonal'.
      """
      init_parameters = dict(locals())
      with tf.name_scope(name or "Seasonal") as name:
          _, observed_stddev, observed_initial = (
              sts_util.empirical_statistics(observed_time_series)
              if observed_time_series is not None
              else (0.0, 1.0, 0.0)
          )
  
          # Heuristic default priors. Overriding these may dramatically
          # change inference performance and results.
          if initial_effect_prior is None:
              initial_effect_prior = normal.Normal(
                  loc=observed_initial,
                  scale=tf.abs(observed_initial) + observed_stddev,
              )
          self.dtype = initial_effect_prior.dtype
          if drift_scale_prior is None:
              scale_factor = tf.convert_to_tensor(
                  0.01, dtype=self.dtype
              )
              drift_scale_prior = lognormal.LogNormal(
                  loc=tf.math.log(scale_factor * observed_stddev),
                  scale=3.0,
              )
  
          if isinstance(initial_effect_prior, normal.Normal):
              initial_state_prior = mvn_diag.MultivariateNormalDiag(
                  loc=tf.stack(
                      [initial_effect_prior.mean()] * num_seasons,
                      axis=-1,
                  ),
                  scale_diag=tf.stack(
                      [initial_effect_prior.stddev()] * num_seasons,
                      axis=-1,
                  ),
              )
          else:
              initial_state_prior = initial_effect_prior
  
          if constrain_mean_effect_to_zero:
              # Transform the prior to the residual parameterization used by
              # `ConstrainedSeasonalStateSpaceModel`, imposing a zero-sum constraint.
              # This doesn't change the marginal prior on individual effects, but
              # does introduce dependence between the effects.
              (
                  effects_to_residuals,
                  _,
              ) = build_effects_to_residuals_matrix(
                  num_seasons, dtype=self.dtype
              )
              effects_to_residuals_linop = (
                  tf.linalg.LinearOperatorFullMatrix(
                      effects_to_residuals
                  )
              )  # Use linop so that matmul broadcasts.
              initial_state_prior_loc = (
                  effects_to_residuals_linop.matvec(
                      initial_state_prior.mean()
                  )
              )
              scale_linop = effects_to_residuals_linop.matmul(
                  initial_state_prior.scale
              )  # returns LinearOperator
              initial_state_prior = mvn_tril.MultivariateNormalTriL(
                  loc=initial_state_prior_loc,
                  scale_tril=tf.linalg.cholesky(
                      scale_linop.matmul(
                          scale_linop.to_dense(), adjoint_arg=True
                      )
                  ),
              )
  
          self._constrain_mean_effect_to_zero = (
              constrain_mean_effect_to_zero
          )
          self._initial_state_prior = initial_state_prior
          self._num_seasons = num_seasons
          self._num_steps_per_season = num_steps_per_season
  
          parameters = []
          if allow_drift:
              parameters.append(
                  Parameter(
                      "drift_scale",
                      drift_scale_prior,
                      chain.Chain(
                          [
                              scale.Scale(scale=observed_stddev),
                              softplus.Softplus(
                                  low=dtype_util.eps(self.dtype)
                              ),
                          ]
                      ),
                  )
              )
          self._allow_drift = allow_drift
  
          super(Seasonal, self).__init__(
              parameters,
              latent_size=(
                  num_seasons - 1
                  if self.constrain_mean_effect_to_zero
                  else num_seasons
              ),
              init_parameters=init_parameters,
              name=name,
          )
  
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import chain
  from tensorflow_probability.python.bijectors import invert
  from tensorflow_probability.python.bijectors import scale
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.bijectors import square
  from tensorflow_probability.python.distributions import inverse_gamma
  from tensorflow_probability.python.distributions import linear_gaussian_ssm
  from tensorflow_probability.python.distributions import lognormal
  from tensorflow_probability.python.distributions import mvn_diag
  from tensorflow_probability.python.distributions import mvn_tril
  from tensorflow_probability.python.distributions import normal
  from tensorflow_probability.python.distributions import transformed_distribution
  from tensorflow_probability.python.experimental.sts_gibbs import sample_parameters
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import docstring_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.sts.internal import util
  from tensorflow_probability.python.sts.structural_time_series import Parameter
  from tensorflow_probability.python.sts.structural_time_series import StructuralTimeSeries
label_desc: Use image node_id 1 to create a new Seasonal object from inherited base classes: StructuralTimeSeries with example: obj = Seasonal(num_seasons, num_steps_per_season, allow_drift, drift_scale_prior, initial_effect_prior, constrain_mean_effect_to_zero, observed_time_series, name)