docstr: Predicts samples, all tensors should have NTC layout.
  Parameters
  ----------
  F
  feat_static_cat : (batch_size, num_features)
  feat_static_real : (batch_size, num_features)
  past_time_feat : (batch_size, history_length, num_features)
  past_target : (batch_size, history_length, *target_shape)
  past_observed_values : (batch_size, history_length, *target_shape)
  future_time_feat : (batch_size, prediction_length, num_features)
  agg_features_dict: Dictionary of features for aggregated levels
  
  Returns
  -------
  Tensor
      Predicted samples
docstr_tok: ["Predicts","samples",",","all","tensors","should","have","NTC","layout",".","Parameters","--","--","--","--","--","F","feat_static_cat",":","(","batch_size",",","num_features",")","feat_static_real",":","(","batch_size",",","num_features",")","past_time_feat",":","(","batch_size",",","history_length",",","num_features",")","past_target",":","(","batch_size",",","history_length",",","*","target_shape",")","past_observed_values",":","(","batch_size",",","history_length",",","*","target_shape",")","future_time_feat",":","(","batch_size",",","prediction_length",",","num_features",")","agg_features_dict",":","Dictionary","of","features","for","aggregated","levels","Returns","--","--","--","-","Tensor","Predicted","samples"]
code: def hybrid_forward(
      self,
      F,
      feat_static_cat: Tensor,  # (batch_size, num_features)
      feat_static_real: Tensor,  # (batch_size, num_features)
      past_time_feat: Tensor,  # (batch_size, history_length, num_features)
      past_target: Tensor,  # (batch_size, history_length, *target_shape)
      past_observed_values: Tensor,  # (batch_size, history_length, *target_shape)
      future_time_feat: Tensor,  # (batch_size, prediction_length, num_features)
      past_is_pad: Tensor,
      agg_features_dict: Dict,
  ) -> Tensor:
      """
      Predicts samples, all tensors should have NTC layout.
      Parameters
      ----------
      F
      feat_static_cat : (batch_size, num_features)
      feat_static_real : (batch_size, num_features)
      past_time_feat : (batch_size, history_length, num_features)
      past_target : (batch_size, history_length, *target_shape)
      past_observed_values : (batch_size, history_length, *target_shape)
      future_time_feat : (batch_size, prediction_length, num_features)
      agg_features_dict: Dictionary of features for aggregated levels
  
      Returns
      -------
      Tensor
          Predicted samples
      """
  
      (
          state_ls,
          scale_ls,
          static_feat_ls,
          past_target_ls,
          future_time_feat_agg_ls,
      ) = ([], [], [], [], [])
  
      for i, agg_multiple in enumerate(
          self.temporal_hierarchy.agg_multiples
      ):
          if agg_multiple != 1:
              past_time_feat_agg = agg_features_dict[f"level_{i}"][
                  "past_time_feat_agg"
              ]
              future_time_feat_agg = agg_features_dict[f"level_{i}"][
                  "future_time_feat_agg"
              ]
          else:
              past_time_feat_agg = past_time_feat
              future_time_feat_agg = future_time_feat
  
          target_related_feat_agg = (
              self.get_target_related_feat_at_agg_level(
                  agg_level=i,
                  past_target=past_target,
                  past_is_pad=past_is_pad,
                  past_observed_values=past_observed_values,
              )
          )
  
          # unroll the decoder in "prediction mode", i.e. with past data only
          _, states, scale, static_feat, imputed_sequence = self.models[
              i
          ].unroll_encoder(
              F=F,
              feat_static_cat=feat_static_cat,
              feat_static_real=feat_static_real,
              past_time_feat=past_time_feat_agg,
              future_observed_values=None,
              future_time_feat=None,
              future_target=None,
              **target_related_feat_agg,
          )
  
          # blows-up the dimension of each tensor to batch_size *
          # self.num_parallel_samples for increasing parallelism
          repeated_past_target = imputed_sequence.repeat(
              repeats=self.num_parallel_samples, axis=0
          )
          repeated_states = [
              s.repeat(repeats=self.num_parallel_samples, axis=0)
              for s in states
          ]
          repeated_time_feat = future_time_feat_agg.repeat(
              repeats=self.num_parallel_samples, axis=0
          )
          repeated_static_feat = static_feat.repeat(
              repeats=self.num_parallel_samples, axis=0
          ).expand_dims(axis=1)
          repeated_scale = scale.repeat(
              repeats=self.num_parallel_samples, axis=0
          )
  
          state_ls.append(repeated_states)
          scale_ls.append(repeated_scale)
          static_feat_ls.append(repeated_static_feat)
          past_target_ls.append(repeated_past_target)
          future_time_feat_agg_ls.append(repeated_time_feat)
  
      reconciled_samples_at_all_levels = self.sampling_decoder(
          F,
          state_ls=state_ls,
          scale_ls=scale_ls,
          static_feat_ls=static_feat_ls,
          past_target_ls=past_target_ls,
          future_time_feat_agg_ls=future_time_feat_agg_ls,
      )
  
      if self.return_forecasts_at_all_levels:
          return reconciled_samples_at_all_levels
      else:
          reconciled_samples_at_bottom_level = (
              reconciled_samples_at_all_levels.slice_axis(
                  axis=-1,
                  begin=-self.temporal_hierarchy.num_leaves,
                  end=None,
              )
          )
  
          reconciled_samples_at_bottom_level = (
              reconciled_samples_at_bottom_level.reshape(
                  (
                      reconciled_samples_at_bottom_level.shape[0],
                      reconciled_samples_at_bottom_level.shape[1],
                      -1,
                  )
              )
          )
  
          return reconciled_samples_at_bottom_level
  
imports: from typing import Dict, List, Optional, Tuple
  import mxnet
  import numpy
  from gluonts.core.component import Type, validated
  from gluonts.itertools import prod
  from gluonts.mx.model.deepar import DeepAREstimator
  from gluonts.mx.model.deepar._network import DeepARPredictionNetwork
  from gluonts.mx.model.deepvar_hierarchical._estimator import projection_mat
  from gluonts.mx.model.deepvar_hierarchical._network import coherency_error
  from gluonts.mx.distribution import Distribution, EmpiricalDistribution
  from gluonts.mx import Tensor
  from gluonts.mx.distribution import TransformedPiecewiseLinear
  from gluonts.nursery.temporal_hierarchical_forecasting.utils import utils
  from gluonts.nursery.temporal_hierarchical_forecasting.model.cop_deepar import gluonts_fixes, gnn
label_desc: Use image node_id 4 for calling the COPDeepARPredictionNetwork obj's underlying member method code with example usage: obj.hybrid_forward(F, feat_static_cat, feat_static_real, past_time_feat, past_target, past_observed_values, future_time_feat, past_is_pad, agg_features_dict) and returns: reconciled_samples_at_all_levels, reconciled_samples_at_bottom_level