docstr: This model is recurrent, so we have to write a specific way to
  obtain the time series forecasts of length n.
docstr_tok: ["This","model","is","recurrent",",","so","we","have","to","write","a","specific","way","to","obtain","the","time","series","forecasts","of","length","n","."]
code: def _get_batch_prediction(
      self, n: int, input_batch: Tuple, roll_size: int
  ) -> torch.Tensor:
      """
      This model is recurrent, so we have to write a specific way to
      obtain the time series forecasts of length n.
      """
      (
          past_target,
          historic_future_covariates,
          future_covariates,
          static_covariates,
      ) = input_batch
  
      if historic_future_covariates is not None:
          # RNNs need as inputs (target[t] and covariates[t+1]) so here we shift the covariates
          all_covariates = torch.cat(
              [historic_future_covariates[:, 1:, :], future_covariates],
              dim=1,
          )
          cov_past, cov_future = (
              all_covariates[:, : past_target.shape[1], :],
              all_covariates[:, past_target.shape[1] :, :],
          )
          input_series = torch.cat([past_target, cov_past], dim=2)
      else:
          input_series = past_target
          cov_future = None
  
      batch_prediction = []
      out, last_hidden_state = self._produce_predict_output(
          (input_series, static_covariates)
      )
      batch_prediction.append(out[:, -1:, :])
      prediction_length = 1
  
      while prediction_length < n:
          # create new input to model from last prediction and current covariates, if available
          new_input = (
              torch.cat(
                  [
                      out[:, -1:, :],
                      cov_future[
                          :,
                          prediction_length - 1 : prediction_length,
                          :,
                      ],
                  ],
                  dim=2,
              )
              if cov_future is not None
              else out[:, -1:, :]
          )
  
          # feed new input to model, including the last hidden state from the previous iteration
          out, last_hidden_state = self._produce_predict_output(
              (new_input, static_covariates), last_hidden_state
          )
  
          # append prediction to batch prediction array, increase counter
          batch_prediction.append(out[:, -1:, :])
          prediction_length += 1
  
      # bring predictions into desired format and drop unnecessary values
      batch_prediction = torch.cat(batch_prediction, dim=1)
      batch_prediction = batch_prediction[:, :n, :]
      return batch_prediction
  
imports: import inspect
  from abc import ABC, abstractmethod
  from typing import Optional, Sequence, Tuple, Type, Union
  import torch
  import torch.nn
  from darts.logging import get_logger, raise_if_not, raise_log
  from darts.models.forecasting.pl_forecasting_module import PLDualCovariatesModule, io_processor
  from darts.models.forecasting.torch_forecasting_model import DualCovariatesTorchModel
  from darts.timeseries import TimeSeries
  from darts.utils.data import DualCovariatesShiftedDataset, TrainingDataset
label_desc: Use image node_id 5 for calling the CustomRNNModule obj's underlying member method code with example usage: obj._get_batch_prediction(n, input_batch, roll_size) and returns: batch_prediction