docstr: A function to simulate future series.
  If the fitted model supports uncertainty e.g. via ``uncertainty_dict``,
  errors are incorporated into the simulations.
  
  Parameters
  ----------
  fut_df : `pandas.DataFrame`
      The data frame which includes the timestamps
      for prediction and any regressors.
  trained_model : `dict`
      A fitted silverkite model which is the output of ``self.forecast``.
  past_df : `pandas.DataFrame`, optional
      A data frame with past values if autoregressive methods are called
      via ``autoreg_dict`` parameter of ``greykite.algo.forecast.silverkite.SilverkiteForecast.py``
  new_external_regressor_df: `pandas.DataFrame`, optional
      Contains the regressors not already included in ``fut_df``.
  include_err : `bool`
      Boolean to determine if errors are to be incorporated in the simulations.
  time_features_ready : `bool`
      Boolean to denote if time features are already given in df or not.
  regressors_ready : `bool`
      Boolean to denote if regressors are already added to data (``fut_df``).
  
  Returns
  -------
  result: `dict`
      A dictionary with following items
  
      - "fut_df": `pandas.DataFrame`
          The same as input dataframe with an added column for the response.
          If value_col already appears in ``fut_df``, it will be over-written.
          If ``uncertainty_dict`` is provided as input,
          it will also contain a ``QUANTILE_SUMMARY_COL`` column.
          Here are the expected columns:
  
          (1) A time column with the column name being ``trained_model["time_col"]``
          (2) The predicted response in ``value_col`` column.
          (3) Quantile summary response in ``QUANTILE_SUMMARY_COL`` column.
              This column only appears if the model includes uncertainty.
          (4) Error std in `ERR_STD_COL` column.
              This column only appears if the model includes uncertainty.
  
      - "x_mat": `pandas.DataFrame`
          Design matrix of the predictive machine-learning model
      - "features_df": `pandas.DataFrame`
          The features dataframe used for prediction.
code: def simulate(
      self,
      fut_df,
      trained_model,
      past_df=None,
      new_external_regressor_df=None,
      include_err=True,
      time_features_ready=False,
      regressors_ready=False,
  ):
      """A function to simulate future series.
      If the fitted model supports uncertainty e.g. via ``uncertainty_dict``,
      errors are incorporated into the simulations.
  
      Parameters
      ----------
      fut_df : `pandas.DataFrame`
          The data frame which includes the timestamps
          for prediction and any regressors.
      trained_model : `dict`
          A fitted silverkite model which is the output of ``self.forecast``.
      past_df : `pandas.DataFrame`, optional
          A data frame with past values if autoregressive methods are called
          via ``autoreg_dict`` parameter of ``greykite.algo.forecast.silverkite.SilverkiteForecast.py``
      new_external_regressor_df: `pandas.DataFrame`, optional
          Contains the regressors not already included in ``fut_df``.
      include_err : `bool`
          Boolean to determine if errors are to be incorporated in the simulations.
      time_features_ready : `bool`
          Boolean to denote if time features are already given in df or not.
      regressors_ready : `bool`
          Boolean to denote if regressors are already added to data (``fut_df``).
  
      Returns
      -------
      result: `dict`
          A dictionary with following items
  
          - "fut_df": `pandas.DataFrame`
              The same as input dataframe with an added column for the response.
              If value_col already appears in ``fut_df``, it will be over-written.
              If ``uncertainty_dict`` is provided as input,
              it will also contain a ``QUANTILE_SUMMARY_COL`` column.
              Here are the expected columns:
  
              (1) A time column with the column name being ``trained_model["time_col"]``
              (2) The predicted response in ``value_col`` column.
              (3) Quantile summary response in ``QUANTILE_SUMMARY_COL`` column.
                  This column only appears if the model includes uncertainty.
              (4) Error std in `ERR_STD_COL` column.
                  This column only appears if the model includes uncertainty.
  
          - "x_mat": `pandas.DataFrame`
              Design matrix of the predictive machine-learning model
          - "features_df": `pandas.DataFrame`
              The features dataframe used for prediction.
  
      """
      n = len(fut_df)
      past_df_sim = None if past_df is None else past_df.copy()
      fut_df = fut_df.reset_index(drop=True)
      fut_df_sim = fut_df.copy()
      time_col = trained_model["time_col"]
      value_col = trained_model["value_col"]
      fut_df_sim[value_col] = np.nan
      fut_df_sim = fut_df_sim.astype({value_col: "float64"})
      max_lag_order = trained_model["max_lag_order"]
      max_lagged_regressor_order = trained_model[
          "max_lagged_regressor_order"
      ]
      # overall maximum lag order
      max_order = None
      if (
          max_lag_order is not None
          and max_lagged_regressor_order is not None
      ):
          max_order = np.max(
              [max_lag_order, max_lagged_regressor_order]
          )
      elif max_lag_order is not None:
          max_order = max_lag_order
      elif max_lagged_regressor_order is not None:
          max_order = max_lagged_regressor_order
  
      # Only need to keep the last relevant rows to calculate AR terms
      if (
          past_df_sim is not None
          and max_order is not None
          and len(past_df_sim) > max_order
      ):
          past_df_sim = past_df_sim.tail(max_order)
  
      # adds the other features
      if time_features_ready is not True:
          fut_df = self.__build_silverkite_features(
              df=fut_df,
              time_col=time_col,
              origin_for_time_vars=trained_model[
                  "origin_for_time_vars"
              ],
              daily_event_df_dict=trained_model["daily_event_df_dict"],
              daily_event_neighbor_impact=trained_model[
                  "daily_event_neighbor_impact"
              ],
              daily_event_shifted_effect=trained_model[
                  "daily_event_shifted_effect"
              ],
              changepoint_values=trained_model["changepoint_values"],
              continuous_time_col=trained_model["continuous_time_col"],
              growth_func=trained_model["growth_func"],
              fs_func=trained_model["fs_func"],
              seasonality_changepoint_result=trained_model[
                  "seasonality_changepoint_result"
              ],
              changepoint_dates=trained_model[
                  "trend_changepoint_dates"
              ],
          )
  
      if new_external_regressor_df is not None and not regressors_ready:
          new_external_regressor_df = (
              new_external_regressor_df.reset_index(drop=True)
          )
          fut_df = pd.concat(
              [fut_df, new_external_regressor_df], axis=1, sort=False
          )
  
      x_mat_list = []
      features_df_list = []
      for i in range(n):
          fut_df_sub = fut_df.iloc[[i]].reset_index(drop=True)
          assert (
              len(fut_df_sub) == 1
          ), "the subset dataframe must have only one row"
  
          pred_res = self.predict_no_sim(
              fut_df=fut_df_sub,
              trained_model=trained_model,
              past_df=past_df_sim,
              new_external_regressor_df=None,
              time_features_ready=True,
              regressors_ready=True,
          )
  
          fut_df_sub = pred_res["fut_df"]
          # we expect the returned prediction will have only one row
          assert len(fut_df_sub) == 1
  
          x_mat = pred_res["x_mat"]
          features_df = pred_res["features_df"]
          x_mat_list.append(x_mat)
          features_df_list.append(features_df)
  
          fut_df_sim.at[i, value_col] = fut_df_sub[value_col].values[0]
  
          if include_err:
              if ERR_STD_COL in list(fut_df_sub.columns):
                  scale = fut_df_sub[ERR_STD_COL].values[0]
                  err = np.random.normal(loc=0.0, scale=scale)
                  fut_df_sim.at[i, value_col] = (
                      fut_df_sub[value_col].values[0] + err
                  )
              else:
                  raise ValueError(
                      "Error is requested via ``include_err = True``. "
                      f"However the std column ({ERR_STD_COL}) "
                      "does not appear in the prediction"
                  )
  
          # Here after assigning values for future forecast, we clip the values based on ``min_admissible_value`` and ``max_admissible_value``
          # saved in ``trained_model``. The clip should only function when error terms are added, as ``predict_no_sim`` ensures the predicted
          # values (before errors are added) are bounded.
          min_admissible_value = trained_model["min_admissible_value"]
          max_admissible_value = trained_model["max_admissible_value"]
          if (
              min_admissible_value is not None
              or max_admissible_value is not None
          ):
              fut_df_sim.at[i, value_col] = np.clip(
                  a=fut_df_sim.at[i, value_col],
                  a_min=min_admissible_value,
                  a_max=max_admissible_value,
              )
  
          # we get the last prediction value and concat that to the end of
          # ``past_df``
          past_df_increment = fut_df_sim.iloc[[i]].reset_index(
              drop=True
          )[[value_col]]
          assert len(past_df_increment) == 1
          if past_df_sim is None:
              past_df_sim = past_df_increment
          else:
              past_df_sim = pd.concat(
                  [past_df_sim, past_df_increment], axis=0, sort=False
              )
  
          # Only need to keep the last relevant rows to calculate AR terms
          if (
              past_df_sim is not None
              and max_order is not None
              and len(past_df_sim) > max_order
          ):
              past_df_sim = past_df_sim.tail(max_order)
          past_df_sim = past_df_sim.reset_index(drop=True)
  
      x_mat = pd.concat(
          x_mat_list,
          axis=0,
          ignore_index=True,  # The index does not matter as we simply want to stack up the data
          sort=False,
      )
      assert len(x_mat) == len(
          fut_df
      ), "The design matrix size (number of rows) used in simulation must have same size as the input"
  
      features_df = pd.concat(
          features_df_list,
          axis=0,
          ignore_index=True,  # The index does not matter as we simply want to stack up the data
          sort=False,
      )
      assert len(features_df) == len(
          fut_df
      ), "The features data size (number of rows) used in simulation must have same size as the input"
  
      return {
          "sim_df": fut_df_sim[[time_col, value_col]],
          "x_mat": x_mat,
          "features_df": features_df,
      }
  
imports: import re
  import warnings
  from typing import Type
  import numpy
  import pandas
  from pandas.plotting import register_matplotlib_converters
  from pandas.tseries.frequencies import to_offset
  from greykite.algo.changepoint.adalasso.changepoint_detector import get_changepoints_dict
  from greykite.algo.changepoint.adalasso.changepoint_detector import get_seasonality_changepoints
  from greykite.algo.changepoint.adalasso.changepoints_utils import build_seasonality_feature_df_from_detection_result
  from greykite.algo.changepoint.adalasso.changepoints_utils import get_seasonality_changepoint_df_cols
  from greykite.algo.common.ml_models import fit_ml_model_with_evaluation
  from greykite.algo.common.ml_models import predict_ml
  from greykite.algo.common.ml_models import predict_ml_with_uncertainty
  from greykite.algo.forecast.silverkite.constants.silverkite_constant import default_silverkite_constant
  from greykite.algo.forecast.silverkite.constants.silverkite_seasonality import SilverkiteSeasonalityEnum
  from greykite.algo.forecast.silverkite.constants.silverkite_seasonality import SilverkiteSeasonalityEnumMixin
  from greykite.algo.forecast.silverkite.forecast_silverkite_helper import get_fourier_feature_col_names
  from greykite.algo.forecast.silverkite.forecast_silverkite_helper import get_similar_lag
  from greykite.common.constants import CHANGEPOINT_COL_PREFIX
  from greykite.common.constants import ERR_STD_COL
  from greykite.common.constants import QUANTILE_SUMMARY_COL
  from greykite.common.constants import SEASONALITY_REGEX
  from greykite.common.constants import TimeFeaturesEnum
  from greykite.common.enums import TimeEnum
  from greykite.common.features.timeseries_features import add_daily_events
  from greykite.common.features.timeseries_features import add_time_features_df
  from greykite.common.features.timeseries_features import fourier_series_multi_fcn
  from greykite.common.features.timeseries_features import get_changepoint_dates_from_changepoints_dict
  from greykite.common.features.timeseries_features import get_changepoint_features
  from greykite.common.features.timeseries_features import get_changepoint_features_and_values_from_config
  from greykite.common.features.timeseries_features import get_default_origin_for_time_vars
  from greykite.common.features.timeseries_lags import build_autoreg_df
  from greykite.common.features.timeseries_lags import build_autoreg_df_multi
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.python_utils import get_pattern_cols
  from greykite.common.python_utils import unique_elements_in_list
  from greykite.common.time_properties import describe_timeseries
  from greykite.common.time_properties import fill_missing_dates
  from greykite.common.time_properties import min_gap_in_seconds
  from greykite.common.time_properties_forecast import get_default_horizon_from_period
label_desc: Use image node_id 5 for calling the SilverkiteForecast obj's underlying member method code with example usage: obj.simulate(fut_df, trained_model, past_df, new_external_regressor_df, include_err, time_features_ready, regressors_ready) and returns: dict