class_docstr: Holt Winter's Exponential Smoothing
  
  Parameters
  ----------
  endog : array_like
      The time series to model.
  trend : {"add", "mul", "additive", "multiplicative", None}, optional
      Type of trend component.
  damped_trend : bool, optional
      Should the trend component be damped.
  seasonal : {"add", "mul", "additive", "multiplicative", None}, optional
      Type of seasonal component.
  seasonal_periods : int, optional
      The number of periods in a complete seasonal cycle, e.g., 4 for
      quarterly data or 7 for daily data with a weekly cycle.
  initialization_method : str, optional
      Method for initialize the recursions. One of:
  
      * None
      * 'estimated'
      * 'heuristic'
      * 'legacy-heuristic'
      * 'known'
  
      None defaults to the pre-0.12 behavior where initial values
      are passed as part of ``fit``. If any of the other values are
      passed, then the initial values must also be set when constructing
      the model. If 'known' initialization is used, then `initial_level`
      must be passed, as well as `initial_trend` and `initial_seasonal` if
      applicable. Default is 'estimated'. "legacy-heuristic" uses the same
      values that were used in statsmodels 0.11 and earlier.
  initial_level : float, optional
      The initial level component. Required if estimation method is "known".
      If set using either "estimated" or "heuristic" this value is used.
      This allows one or more of the initial values to be set while
      deferring to the heuristic for others or estimating the unset
      parameters.
  initial_trend : float, optional
      The initial trend component. Required if estimation method is "known".
      If set using either "estimated" or "heuristic" this value is used.
      This allows one or more of the initial values to be set while
      deferring to the heuristic for others or estimating the unset
      parameters.
  initial_seasonal : array_like, optional
      The initial seasonal component. An array of length `seasonal`
      or length `seasonal - 1` (in which case the last initial value
      is computed to make the average effect zero). Only used if
      initialization is 'known'. Required if estimation method is "known".
      If set using either "estimated" or "heuristic" this value is used.
      This allows one or more of the initial values to be set while
      deferring to the heuristic for others or estimating the unset
      parameters.
  use_boxcox : {True, False, 'log', float}, optional
      Should the Box-Cox transform be applied to the data first? If 'log'
      then apply the log. If float then use the value as lambda.
  bounds : dict[str, tuple[float, float]], optional
      An dictionary containing bounds for the parameters in the model,
      excluding the initial values if estimated. The keys of the dictionary
      are the variable names, e.g., smoothing_level or initial_slope.
      The initial seasonal variables are labeled initial_seasonal.<j>
      for j=0,...,m-1 where m is the number of period in a full season.
      Use None to indicate a non-binding constraint, e.g., (0, None)
      constrains a parameter to be non-negative.
  dates : array_like of datetime, optional
      An array-like object of datetime objects. If a Pandas object is given
      for endog, it is assumed to have a DateIndex.
  freq : str, optional
      The frequency of the time-series. A Pandas offset or 'B', 'D', 'W',
      'M', 'A', or 'Q'. This is optional if dates are given.
  missing : str
      Available options are 'none', 'drop', and 'raise'. If 'none', no nan
      checking is done. If 'drop', any observations with nans are dropped.
      If 'raise', an error is raised. Default is 'none'.
  
  Notes
  -----
  This is a full implementation of the holt winters exponential smoothing as
  per [1]_. This includes all the unstable methods as well as the stable
  methods. The implementation of the library covers the functionality of the
  R library as much as possible whilst still being Pythonic.
  
  See the notebook `Exponential Smoothing
  <../examples/notebooks/generated/exponential_smoothing.html>`__
  for an overview.
  
  References
  ----------
  .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles
      and practice. OTexts, 2014.
code: def _optimize_parameters(
      self, data: _OptConfig, use_brute, method, kwargs
  ) -> _OptConfig:
      # Prepare starting values
      alpha = data.alpha
      beta = data.beta
      phi = data.phi
      gamma = data.gamma
      y = data.y
      start_params = data.params
  
      has_seasonal = self.has_seasonal
      has_trend = self.has_trend
      trend = self.trend
      seasonal = self.seasonal
      damped_trend = self.damped_trend
  
      m = self.seasonal_periods
      params = np.zeros(6 + m)
      l0, b0, s0 = self.initial_values(
          initial_level=data.level, initial_trend=data.trend
      )
  
      init_alpha = alpha if alpha is not None else 0.5 / max(m, 1)
      init_beta = beta
      if beta is None and has_trend:
          init_beta = 0.1 * init_alpha
      init_gamma = gamma
      if has_seasonal and gamma is None:
          init_gamma = 0.05 * (1 - init_alpha)
      init_phi = phi if phi is not None else 0.99
      # Selection of parameters to optimize
      sel = np.array(
          [
              alpha is None,
              has_trend and beta is None,
              has_seasonal and gamma is None,
              self._estimate_level,
              self._estimate_trend,
              damped_trend and phi is None,
          ]
          + [has_seasonal and self._estimate_seasonal] * m,
      )
      (
          sel,
          init_alpha,
          init_beta,
          init_gamma,
          init_phi,
          l0,
          b0,
          s0,
      ) = self._update_for_fixed(
          sel, init_alpha, init_beta, init_gamma, init_phi, l0, b0, s0
      )
  
      func = SMOOTHERS[(seasonal, trend)]
      params[:6] = [init_alpha, init_beta, init_gamma, l0, b0, init_phi]
      if m:
          params[-m:] = s0
      if not np.any(sel):
          from statsmodels.tools.sm_exceptions import EstimationWarning
  
          message = (
              "Model has no free parameters to estimate. Set "
              "optimized=False to suppress this warning"
          )
          warnings.warn(message, EstimationWarning, stacklevel=3)
          data = data.unpack_parameters(params)
          data.params = params
          data.mask = sel
  
          return data
      orig_bounds = self._construct_bounds()
  
      bounds = np.array(orig_bounds[:3], dtype=float)
      hw_args = HoltWintersArgs(
          sel.astype(int), params, bounds, y, m, self.nobs
      )
      params = self._get_starting_values(
          params,
          start_params,
          use_brute,
          sel,
          hw_args,
          bounds,
          init_alpha,
          func,
      )
  
      # We always use [0, 1] for a, b and g and handle transform inside
      mod_bounds = [(0, 1)] * 3 + orig_bounds[3:]
      relevant_bounds = [
          bnd for bnd, flag in zip(mod_bounds, sel) if flag
      ]
      bounds = np.array(relevant_bounds, dtype=float)
      lb, ub = bounds.T
      lb[np.isnan(lb)] = -np.inf
      ub[np.isnan(ub)] = np.inf
      hw_args.xi = sel.astype(int)
  
      # Ensure strictly inbounds
      initial_p = self._enforce_bounds(params, sel, lb, ub)
      # Transform to unrestricted space
      params[sel] = initial_p
      params[:3] = to_unrestricted(params, sel, hw_args.bounds)
      initial_p = params[sel]
      # Ensure parameters are transformed internally
      hw_args.transform = True
      if method in ("least_squares", "ls"):
          # Least squares uses a different format for bounds
          ls_bounds = lb, ub
          self._check_blocked_keywords(kwargs, ("args", "bounds"))
          res = least_squares(
              func,
              initial_p,
              bounds=ls_bounds,
              args=(hw_args,),
              **kwargs,
          )
          success = res.success
      elif method in ("basinhopping", "bh"):
          # Take a deeper look in the local minimum we are in to find the
          # best solution to parameters, maybe hop around to try escape the
          # local minimum we may be in.
          minimizer_kwargs = {
              "args": (hw_args,),
              "bounds": relevant_bounds,
          }
          kwargs = kwargs.copy()
          if "minimizer_kwargs" in kwargs:
              self._check_blocked_keywords(
                  kwargs["minimizer_kwargs"],
                  ("args", "bounds"),
                  name="kwargs['minimizer_kwargs']",
              )
              minimizer_kwargs.update(kwargs["minimizer_kwargs"])
              del kwargs["minimizer_kwargs"]
          default_kwargs = {
              "minimizer_kwargs": minimizer_kwargs,
              "stepsize": 0.01,
          }
          default_kwargs.update(kwargs)
          obj = opt_wrapper(func)
          res = basinhopping(obj, initial_p, **default_kwargs)
          success = res.lowest_optimization_result.success
      else:
          obj = opt_wrapper(func)
          self._check_blocked_keywords(
              kwargs, ("args", "bounds", "method")
          )
          res = minimize(
              obj,
              initial_p,
              args=(hw_args,),
              bounds=relevant_bounds,
              method=method,
              **kwargs,
          )
          success = res.success
      # finally transform to restricted space
      params[sel] = res.x
      params[:3] = to_restricted(params, sel, hw_args.bounds)
      res.x = params[sel]
  
      if not success:
          from statsmodels.tools.sm_exceptions import ConvergenceWarning
  
          warnings.warn(
              "Optimization failed to converge. Check mle_retvals.",
              ConvergenceWarning,
          )
      params[sel] = res.x
  
      data.unpack_parameters(params)
      data.params = params
      data.mask = sel
      data.mle_retvals = res
  
      return data
  
imports: from statsmodels.compat.pandas import deprecate_kwarg
  import contextlib
  from typing import Any
  from collections.abc import Hashable, Sequence
  import warnings
  import numpy
  import pandas
  from scipy.optimize import basinhopping, least_squares, minimize
  from scipy.special import inv_boxcox
  from scipy.stats import boxcox
  from statsmodels.tools.validation import array_like, bool_like, dict_like, float_like, int_like, string_like
  from statsmodels.tsa.base.tsa_model import TimeSeriesModel
  from statsmodels.tsa.exponential_smoothing.ets import _initialization_heuristic, _initialization_simple
  from statsmodels.tsa.holtwinters import _exponential_smoothers, _smoothers
  from statsmodels.tsa.holtwinters._exponential_smoothers import HoltWintersArgs
  from statsmodels.tsa.holtwinters._smoothers import to_restricted, to_unrestricted
  from statsmodels.tsa.holtwinters.results import HoltWintersResults, HoltWintersResultsWrapper
  from statsmodels.tsa.tsatools import freq_to_period
label_desc: Use image node_id 19 for calling the ExponentialSmoothing obj's underlying member method code with example usage: obj._optimize_parameters(data, use_brute, method, kwargs) and returns: data, data