code: def ets_target_fn(
      par,
      p_y,
      p_nstate,
      p_errortype,
      p_trendtype,
      p_seasontype,
      p_damped,
      p_lower,
      p_upper,
      p_opt_crit,
      p_nmse,
      p_bounds,
      p_m,
      p_optAlpha,
      p_optBeta,
      p_optGamma,
      p_optPhi,
      p_givenAlpha,
      p_givenBeta,
      p_givenGamma,
      p_givenPhi,
      alpha,
      beta,
      gamma,
      phi,
  ):
      # p_par_length = len(par)
      j = 0
      if p_optAlpha:
          alpha = par[j]
          j += 1
      if p_optBeta:
          beta = par[j]
          j += 1
      if p_optGamma:
          gamma = par[j]
          j += 1
      if p_optPhi:
          phi = par[j]
      # size of state
      p = p_nstate + (1 if p_seasontype != 0 else 0)
      n = len(p_y)
      state = np.zeros(p * (n + 1))
      state[:p_nstate] = par[-p_nstate:]
      # Add extra state
      if p_seasontype != 0:
          start = 1 + (1 if p_trendtype != 0 else 0)
          sum_ = state[start:p_nstate].sum()
          new_state = p_m * (1 if p_seasontype == 2 else 0) - sum_
          state[p_nstate] = new_state
          # check states
          if p_seasontype == 2 and state[start:].min() < 0:
              return np.inf
      amse = np.zeros(30)
      e = np.zeros(n)
      lik = etscalc(
          # we dont need to change these param
          p_y,
          n,
          state,
          p_m,
          p_errortype,
          p_trendtype,
          p_seasontype,
          # inmutable, wee need to change them?
          alpha,
          beta,
          gamma,
          phi,
          # mutable
          e,
          amse,
          # inmutable
          p_nmse,
      )
      if lik < -1e10:
          lik = -1e10
      if math.isnan(lik):
          lik = -np.inf
      if math.fabs(lik + 99999) < 1e-7:
          lik = -np.inf
      if p_opt_crit == "lik":
          objval = lik
      elif p_opt_crit == "mse":
          objval = amse[0]
      elif p_opt_crit == "amse":
          mean = 0.0
          for i in range(p_nmse):
              mean += amse[i] / p_nmse
          objval = mean
      elif p_opt_crit == "sigma":
          mean = 0.0
          ne = len(e)
          for i in range(ne):
              mean += e[i] * e[i] / ne
          objval = mean
      elif p_opt_crit == "mae":
          mean = 0
          ne = len(e)
          for i in range(ne):
              mean += math.fabs(e[i]) / ne
          objval = mean
      return objval
  
imports: import math
  from collections import namedtuple
  from typing import Tuple
  import numpy
  from numba import njit
  from numba.typed import List
  from statsmodels.tsa.seasonal import seasonal_decompose
  from .utils import _calculate_intervals, CACHE, NOGIL
label_desc: Use image node_id 17 for calling a global function with example usage: ets_target_fn(par, p_y, p_nstate, p_errortype, p_trendtype, p_seasontype, p_damped, p_lower, p_upper, p_opt_crit, p_nmse, p_bounds, p_m, p_optAlpha, p_optBeta, p_optGamma, p_optPhi, p_givenAlpha, p_givenBeta, p_givenGamma, p_givenPhi, alpha, beta, gamma, phi) and returns: objval, np