docstr: Performs predictions for the dates in ``fut_df``.
  If ``extra_pred_cols`` refers to a column in ``df``, either ``fut_df``
  or ``new_external_regressor_df`` must contain the regressors and the columns needed for lagged regressors.
  
  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`.
  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``).
  
  Return
  --------
  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.
      - "x_mat": `pandas.DataFrame`
          Design matrix of the predictive machine-learning model
      - "features_df": `pandas.DataFrame`
          The features dataframe used for prediction.
code: def predict_no_sim(
      self,
      fut_df,
      trained_model,
      past_df=None,
      new_external_regressor_df=None,
      time_features_ready=False,
      regressors_ready=False,
  ):
      """Performs predictions for the dates in ``fut_df``.
      If ``extra_pred_cols`` refers to a column in ``df``, either ``fut_df``
      or ``new_external_regressor_df`` must contain the regressors and the columns needed for lagged regressors.
  
      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`.
      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``).
  
      Return
      --------
      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.
          - "x_mat": `pandas.DataFrame`
              Design matrix of the predictive machine-learning model
          - "features_df": `pandas.DataFrame`
              The features dataframe used for prediction.
  
      """
      fut_df = fut_df.copy()
      time_col = trained_model["time_col"]
      value_col = trained_model["value_col"]
      max_lag_order = trained_model["max_lag_order"]
      max_lagged_regressor_order = trained_model[
          "max_lagged_regressor_order"
      ]
      min_lagged_regressor_order = trained_model[
          "min_lagged_regressor_order"
      ]
      lagged_regressor_cols = trained_model["lagged_regressor_cols"]
  
      if max_lag_order is not None and (
          past_df is None or past_df.shape[0] < max_lag_order
      ):
          warnings.warn(
              "The autoregression lags data had to be interpolated at predict time."
              "`past_df` was either not passed to `predict_silverkite` "
              "or it was not long enough to calculate all necessery lags "
              f"which is equal to `max_lag_order`={max_lag_order}"
          )
  
      if max_lagged_regressor_order is not None and (
          past_df is None
          or past_df.shape[0] < max_lagged_regressor_order
      ):
          warnings.warn(
              "The lagged regressor data had to be interpolated at predict time."
              "`past_df` was either not passed to `predict_silverkite` "
              "or it was not long enough to calculate all necessery lags "
              f"which is equal to `max_lagged_regressor_order`={max_lagged_regressor_order}"
          )
  
      # This is the 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
      # We only keep the rows needed in ``past_df``
      if (
          past_df is not None
          and max_order is not None
          and len(past_df) > max_order
      ):
          past_df = past_df.tail(max_order).reset_index(drop=True)
  
      # adds extra regressors if provided
      if new_external_regressor_df is None or regressors_ready:
          features_df_fut = fut_df
      else:
          new_external_regressor_df = (
              new_external_regressor_df.reset_index(drop=True)
          )
          features_df_fut = pd.concat(
              [fut_df, new_external_regressor_df], axis=1, sort=False
          )
  
      # adds the other features
      if time_features_ready is not True:
          features_df_fut = self.__build_silverkite_features(
              df=features_df_fut,
              time_col=trained_model["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"
              ],
          )
  
      # adds autoregression columns to future feature matrix
      if trained_model["autoreg_func"] is not None:
          if past_df is None:
              raise ValueError(
                  "Autoregression was used but no past_df was passed to "
                  "`predict_no_sim`"
              )
          else:
              # If the timestamps in ``fut_df`` are all before ``train_end_timestamp``,
              # then the phase is to calculate fitted values.
              # In this case if there are any values in ``fut_df``,
              # they can be used since the information is known by ``train_end_timestamp``.
              train_end_timestamp = trained_model["max_timestamp"]
              fut_df_max_timestamp = pd.to_datetime(
                  fut_df[time_col]
              ).max()
              phase = (
                  "predict"
                  if train_end_timestamp < fut_df_max_timestamp
                  else "fit"
              )
              if phase == "predict":
                  # If phase is predict, we do not allow using ``value_col``.
                  # The AR lags should be enough since otherwise one would use ``predict_via_sim``.
                  df = pd.DataFrame(
                      {value_col: [np.nan] * fut_df.shape[0]}
                  )
                  df.index = fut_df.index
              else:
                  # If phase is fit, we keep the values in ``value_col``.
                  df = fut_df[[value_col]].copy()
              autoreg_df = self.__build_autoreg_features(
                  df=df,
                  value_col=trained_model["value_col"],
                  autoreg_func=trained_model["autoreg_func"],
                  phase=phase,
                  past_df=past_df[[value_col]],
              )
              features_df_fut = pd.concat(
                  [features_df_fut, autoreg_df], axis=1, sort=False
              )
  
      # adds lagged regressor columns to future feature matrix
      if trained_model["lagged_regressor_func"] is not None:
          if past_df is None:
              raise ValueError(
                  "Lagged regressor(s) were used but no past_df was passed to "
                  "`predict_no_sim`"
              )
          else:
              # `build_lagged_regressor_features` requires both ``df`` and ``past_df``
              # to contain the columns needed for lagged regressors
              # case 1: ``min_lagged_regressor_order`` >= ``fut_df.shape[0]``
              # In this case we do not need ``fut_df`` to contain any values for
              # those columns, but we do need to make sure these columns are included
              # as required by `build_lagged_regressor_features`.
              if min_lagged_regressor_order >= fut_df.shape[0]:
                  for col in lagged_regressor_cols:
                      if col not in fut_df.columns:
                          features_df_fut[col] = np.nan
              # case 2: ``min_lagged_regressor_order`` < ``fut_df.shape[0]``
              # In this case ``fut_df`` has to contain those columns, and an error
              # will be raised when `build_lagged_regressor_features` is called.
              lagged_regressor_df = (
                  self.__build_lagged_regressor_features(
                      df=features_df_fut.copy(),
                      lagged_regressor_cols=trained_model[
                          "lagged_regressor_cols"
                      ],
                      lagged_regressor_func=trained_model[
                          "lagged_regressor_func"
                      ],
                      phase="predict",
                      past_df=past_df[
                          trained_model["lagged_regressor_cols"]
                      ],
                  )
              )
              features_df_fut = pd.concat(
                  [features_df_fut, lagged_regressor_df],
                  axis=1,
                  sort=False,
              )
  
      if value_col in features_df_fut.columns:
          # This is to remove duplicate ``value_col`` generated by building features.
          # The duplicates happen during calculating extended fitted values
          # when we intentionally include ``value_col``.
          del features_df_fut[value_col]
      features_df_fut[value_col] = 0.0
      if trained_model["uncertainty_dict"] is None:
          # predictions are stored to ``value_col``
          pred_res = predict_ml(
              fut_df=features_df_fut, trained_model=trained_model
          )
          fut_df = pred_res["fut_df"]
          x_mat = pred_res["x_mat"]
      else:
          # predictions are stored to ``value_col``
          # quantiles are stored to ``QUANTILE_SUMMARY_COL``
          pred_res = predict_ml_with_uncertainty(
              fut_df=features_df_fut, trained_model=trained_model
          )
          fut_df = pred_res["fut_df"]
          x_mat = pred_res["x_mat"]
  
      # Makes sure to return only necessary columns
      potential_forecast_cols = [
          time_col,
          value_col,
          QUANTILE_SUMMARY_COL,
          ERR_STD_COL,
      ]
      existing_forecast_cols = [
          col
          for col in potential_forecast_cols
          if col in fut_df.columns
      ]
      fut_df = fut_df[existing_forecast_cols]
  
      return {
          "fut_df": fut_df,
          "x_mat": x_mat,
          "features_df": features_df_fut,
      }
  
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 3 for calling the SilverkiteForecast obj's underlying member method code with example usage: obj.predict_no_sim(fut_df, trained_model, past_df, new_external_regressor_df, time_features_ready, regressors_ready) and returns: dict