class_docstr: A class to enable easy implementation of optimization over
  arbitrary parameter spaces and using arbitrary rewards.
  The optimization problem can be stated in pseudo code:
  
  Maximize_{param} reward(some_function(param))
  
  Note that 'reward(some_function(param))' can be considered as the objective
  which is to be maximized. The objective is a two part calculation in this framework
  
      - calculate a function for param
      - calculate the reward for the above
  
  Here is a more detailed mathematical explanation in more detailed pseudo code:
  
  Assume:
      - ``param`` is a (potentially multivariate) parameter in a parameter space ``param_iterable``
      - ``calc_with_param`` is a function which depends on ``param``
      - psudeo code: 'calc_result = calc_with_param(param, ...)'
      - psudeo code: 'obj_value = reward.apply(calc_result.data)'
  
  Goal:
      - optimize (maximize) 'obj_value' across all possible param
  
  Note that `reward` does not take ``param`` as an input and only applied to
  the updated data calculated using ``param``.
  
  The class initializes by passing an arbitrary ``reward``
  for optimization and a potentially multivariate parameter
  (given in ``param_iterable``) to optimize.
  
  The ``reward`` object is required to implement the ``apply`` method
  which is the case for this class:
  `~greykite.detection.detector.reward.Reward`
  
  The optimization method (``optimize_param``) is the main method in this class and
  works simply by iterating over ``param_iterable`` and calculating the reward
  to choose the optimal parameter.
  The class assumes that larger is better for the reward function, during optimization.
  
  The classes inherting this class, need to implement ``calc_with_param`` method to be able to use the optimizer and given that implementation.
  
  Parameters
  ----------
  reward : `~greykite.detection.detector.reward.Reward` or None, default None
      The reward to be used in the optimization.
  param_iterable : iterable or None, default None
      An iterable with every element being a parameter passed to the method
      ``calc_with_param`` which takes ``param`` as one of its arguments and
      ``data`` as the other.
      Each ``param`` can be a dictionary including values for a set of variables.
      The optimizer method (``optimize_param``) will iterate over all the
      parameters to find the best parameter in terms of the specified reward.
  
  Attributes
  ----------
  data : `dataclasses.dataclass` or None, default None
      A data class object which includes the data for fitting or
      prediction. Depending on the model, this data class might
      include various fields. A simple example is given in
      `~greykite.detection.detector.data.Data`
  fit_info : `dict`
      A dictionary which includes information about the fitted model.
      It is expected that this includes ``"full_param"`` after the fitting
      so that the `predict` function can use that param during the prediction
      and simply call `calc_with_param`.
      In that case the `predict` function does not need further implementation
      in child classes as it's already implemented in this class.
docstr: This is a calculation step which uses both ``data`` and ``param``.
  This is typically expected to be implemented by user.
  By default, it simply returns the data without any alteration.
  However, in general the data will be altered in various ways
  depending on the ``param`` passed.
  
  Parameters
  ----------
  param : `Any`
      One element of `param_iterable`.
      Typically a dictionary which includes the values of a set of parameters
      given in its keys. However it could also be simply a float if `param_iterable`
      is a list of floats.
  data : `dataclasses.dataclass` or None, default None
      The `data` is typically updated in this function after
      we use the given `param` in the calculation here.
      The data is then returned as a part of returned `CalcResult`.
  
  Returns
  -------
  calc_result : `greykite.detection.detector.optimizer.CalcResult`
      The optimization results.
docstr_tok: ["This","is","a","calculation","step","which","uses","both","``","data","``","and","``","param","``",".","This","is","typically","expected","to","be","implemented","by","user",".","By","default",",","it","simply","returns","the","data","without","any","alteration",".","However",",","in","general","the","data","will","be","altered","in","various","ways","depending","on","the","``","param","``","passed",".","Parameters","--","--","--","--","--","param",":","`","Any","`","One","element","of","`","param_iterable","`",".","Typically","a","dictionary","which","includes","the","values","of","a","set","of","parameters","given","in","its","keys",".","However","it","could","also","be","simply","a","float","if","`","param_iterable","`","is","a","list","of","floats",".","data",":","`","dataclasses.dataclass","`","or","None",",","default","None","The","`","data","`","is","typically","updated","in","this","function","after","we","use","the","given","`","param","`","in","the","calculation","here",".","The","data","is","then","returned","as","a","part","of","returned","`","CalcResult","`",".","Returns","--","--","--","-","calc_result",":","`","greykite.detection.detector.optimizer.CalcResult","`","The","optimization","results","."]
code: def calc_with_param(self, param, data=None, **kwargs):
      """This is a calculation step which uses both ``data`` and ``param``.
      This is typically expected to be implemented by user.
      By default, it simply returns the data without any alteration.
      However, in general the data will be altered in various ways
      depending on the ``param`` passed.
  
      Parameters
      ----------
      param : `Any`
          One element of `param_iterable`.
          Typically a dictionary which includes the values of a set of parameters
          given in its keys. However it could also be simply a float if `param_iterable`
          is a list of floats.
      data : `dataclasses.dataclass` or None, default None
          The `data` is typically updated in this function after
          we use the given `param` in the calculation here.
          The data is then returned as a part of returned `CalcResult`.
  
      Returns
      -------
      calc_result : `greykite.detection.detector.optimizer.CalcResult`
          The optimization results.
      """
      return CalcResult(data=data, model=None)
  
file_path: greykite/greykite/detection/detector/optimizer.py
imports: import dataclasses
  from abc import abstractmethod
  from dataclasses import dataclass
  from typing import Optional
  from greykite.detection.detector.data import DetectorData
label_desc: Use image node_id 3 for calling the Optimizer obj's underlying member method code with example usage: obj.calc_with_param(param, data) and returns: CalcResult