class_docstr: Tests the `create_lagged_training_data` function defined in `darts.utils.data.tabularization`. There are broadly
  two 'groups' of tests defined in this module:
      1. 'Generated Test Cases': these test that `create_lagged_training_data` produces the same outputs
      as a simplified implementation of the 'time intersection' feature generation method (see
      `darts.utils.data.tabularization` for further details). For these tests, the 'correct answer' is not
      directly specified; instead, it is generated from a set of input parameters using the set of simplified
      functions. The rationale behind this approach is that it allows for many different combinations of input
      values to be effortlessly tested. The drawback of this, however, is that the correctness of these tests
      assumes that the simplified functions have been implemented correctly - if this isn't the case, then these
      tests are not to be trusted. In saying this, these simplified functions are significantly easier to
      understand and debug than the `create_lagged_training_data` function they're helping to test.
      2. 'Specified Test Cases': these test that `create_lagged_training_data` returns an exactly specified
      output; these specified outputs are *not* 'generated' by another function. Although these 'specified'
      test cases tend to be simpler and less extensive than the 'generated' test cases, their correctness does
      not assume the correct implementation of any other function.
class_docstr_tok: ["Tests","the","`","create_lagged_training_data","`","function","defined","in","`","darts.utils.data.tabularization","`",".","There","are","broadly","two","'groups","'","of","tests","defined","in","this","module",":","1",".","'Generated","Test","Cases","'",":","these","test","that","`","create_lagged_training_data","`","produces","the","same","outputs","as","a","simplified","implementation","of","the","'time","intersection","'","feature","generation","method","(","see","`","darts.utils.data.tabularization","`","for","further","details",")",".","For","these","tests",",","the","'correct","answer","'","is","not","directly","specified",";","instead",",","it","is","generated","from","a","set","of","input","parameters","using","the","set","of","simplified","functions",".","The","rationale","behind","this","approach","is","that","it","allows","for","many","different","combinations","of","input","values","to","be","effortlessly","tested",".","The","drawback","of","this",",","however",",","is","that","the","correctness","of","these","tests","assumes","that","the","simplified","functions","have","been","implemented","correctly","-","if","this","is","n't","the","case",",","then","these","tests","are","not","to","be","trusted",".","In","saying","this",",","these","simplified","functions","are","significantly","easier","to","understand","and","debug","than","the","`","create_lagged_training_data","`","function","they","'re","helping","to","test",".","2",".","'Specified","Test","Cases","'",":","these","test","that","`","create_lagged_training_data","`","returns","an","exactly","specified","output",";","these","specified","outputs","are","*","not","*","'generated","'","by","another","function",".","Although","these","'specified'","test","cases","tend","to","be","simpler","and","less","extensive","than","the","'generated","'","test","cases",",","their","correctness","does","not","assume","the","correct","implementation","of","any","other","function","."]
docstr: Helper function called by `get_feature_times` that extracts all of the times within
  `future_covariates` that can be used to create features.
  
  Unlike the lag values for `target_series` and `past_covariates`, the values in
  `future_covariates_lags` can be negative, zero, or positive. This means that
  `min_lag = -max(future_covariates_lags)` and `max_lag = -min(future_covariates_lags)`
  are *not* guaranteed to be positive here: they could be negative (corresponding to
  a positive value in `future_covariates_lags`), zero, or positive (corresponding to
  a negative value in `future_covariates_lags`). With that being said, the relationship
  `min_lag <= max_lag` always holds.
  
  Consequently, we need to consider three scenarios when finding feature times
  for `future_covariates`:
      1. Both `min_lag` and `max_lag` are positive, which indicates that all of
      the lag values in `future_covariates_lags` are negative (i.e. only values before
      time `t` are used to create a feature from time `t`). In this case, `min_lag`
      and `max_lag` correspond to the smallest magnitude and largest magnitude *negative*
      lags in `future_covariates_lags` respectively. This means we *can* create features for
      times that extend beyond the end of `future_covariates`; additionally, we're unable
      to create features for the first `min_lag` times (see docstring for `get_feature_times_past`).
      2. Both `min_lag` and `max_lag` are non-positive. In this case, `abs(min_lag)` and `abs(max_lag)`
      correspond to the largest and smallest magnitude lags in `future_covariates_lags` respectively;
      note that, somewhat confusingly, `abs(max_lag) <= abs(min_lag)` here. This means that we *can* create f
      features for times that occur before the start of `future_covariates`; the reasoning for this is
      basically the inverse of Case 1 (i.e. we only need to know the values from times `t + abs(max_lag)`
      to `t + abs(min_lag)` to create a feature for time `t`). Additionally, we're unable to create features
      for the last `abs(min_lag)` times in the series, since these times do not have `abs(min_lag)` values
      after them.
      3. `min_lag` is non-positive (i.e. zero or negative), but `max_lag` is positive. In this case,
      `abs(min_lag)` is the magnitude of the largest *non-negative* lag value in `future_covariates_lags`
      and `max_lag` is the largest *negative* lag value in `future_covariates_lags`. This means that we
      *cannot* create features for times that occur before the start of `future_covariates`, nor for
      times that occur after the end of `future_covariates`; this is because we must have access to
      both times before *and* after time `t` to create a feature for this time, which clearly can't
      be acieved for times extending before the start or after the end of the series. Moreover,
      we must exclude the first `max_lag` times and the last `abs(min_lag)` times, since these
      times do not have enough values before or after them respectively.
docstr_tok: ["Helper","function","called","by","`","get_feature_times","`","that","extracts","all","of","the","times","within","`","future_covariates","`","that","can","be","used","to","create","features",".","Unlike","the","lag","values","for","`","target_series","`","and","`","past_covariates","`",",","the","values","in","`","future_covariates_lags","`","can","be","negative",",","zero",",","or","positive",".","This","means","that","`","min_lag","=","-max","(","future_covariates_lags",")","`","and","`","max_lag","=","-min","(","future_covariates_lags",")","`","are","*","not","*","guaranteed","to","be","positive","here",":","they","could","be","negative","(","corresponding","to","a","positive","value","in","`","future_covariates_lags","`",")",",","zero",",","or","positive","(","corresponding","to","a","negative","value","in","`","future_covariates_lags","`",")",".","With","that","being","said",",","the","relationship","`","min_lag","<","=","max_lag","`","always","holds",".","Consequently",",","we","need","to","consider","three","scenarios","when","finding","feature","times","for","`","future_covariates","`",":","1",".","Both","`","min_lag","`","and","`","max_lag","`","are","positive",",","which","indicates","that","all","of","the","lag","values","in","`","future_covariates_lags","`","are","negative","(","i.e",".","only","values","before","time","`","t","`","are","used","to","create","a","feature","from","time","`","t","`",")",".","In","this","case",",","`","min_lag","`","and","`","max_lag","`","correspond","to","the","smallest","magnitude","and","largest","magnitude","*","negative","*","lags","in","`","future_covariates_lags","`","respectively",".","This","means","we","*","can","*","create","features","for","times","that","extend","beyond","the","end","of","`","future_covariates","`",";","additionally",",","we","'re","unable","to","create","features","for","the","first","`","min_lag","`","times","(","see","docstring","for","`","get_feature_times_past","`",")",".","2",".","Both","`","min_lag","`","and","`","max_lag","`","are","non-positive",".","In","this","case",",","`","abs","(","min_lag",")","`","and","`","abs","(","max_lag",")","`","correspond","to","the","largest","and","smallest","magnitude","lags","in","`","future_covariates_lags","`","respectively",";","note","that",",","somewhat","confusingly",",","`","abs","(","max_lag",")","<","=","abs","(","min_lag",")","`","here",".","This","means","that","we","*","can","*","create","f","features","for","times","that","occur","before","the","start","of","`","future_covariates","`",";","the","reasoning","for","this","is","basically","the","inverse","of","Case","1","(","i.e",".","we","only","need","to","know","the","values","from","times","`","t","+","abs","(","max_lag",")","`","to","`","t","+","abs","(","min_lag",")","`","to","create","a","feature","for","time","`","t","`",")",".","Additionally",",","we","'re","unable","to","create","features","for","the","last","`","abs","(","min_lag",")","`","times","in","the","series",",","since","these","times","do","not","have","`","abs","(","min_lag",")","`","values","after","them",".","3",".","`","min_lag","`","is","non-positive","(","i.e",".","zero","or","negative",")",",","but","`","max_lag","`","is","positive",".","In","this","case",",","`","abs","(","min_lag",")","`","is","the","magnitude","of","the","largest","*","non-negative","*","lag","value","in","`","future_covariates_lags","`","and","`","max_lag","`","is","the","largest","*","negative","*","lag","value","in","`","future_covariates_lags","`",".","This","means","that","we","*","can","not","*","create","features","for","times","that","occur","before","the","start","of","`","future_covariates","`",",","nor","for","times","that","occur","after","the","end","of","`","future_covariates","`",";","this","is","because","we","must","have","access","to","both","times","before","*","and","*","after","time","`","t","`","to","create","a","feature","for","this","time",",","which","clearly","can't","be","acieved","for","times","extending","before","the","start","or","after","the","end","of","the","series",".","Moreover",",","we","must","exclude","the","first","`","max_lag","`","times","and","the","last","`","abs","(","min_lag",")","`","times",",","since","these","times","do","not","have","enough","values","before","or","after","them","respectively","."]
code: def get_feature_times_future(
      future_covariates: TimeSeries,
      future_covariates_lags: Sequence[int],
  ) -> pd.Index:
      """
      Helper function called by `get_feature_times` that extracts all of the times within
      `future_covariates` that can be used to create features.
  
      Unlike the lag values for `target_series` and `past_covariates`, the values in
      `future_covariates_lags` can be negative, zero, or positive. This means that
      `min_lag = -max(future_covariates_lags)` and `max_lag = -min(future_covariates_lags)`
      are *not* guaranteed to be positive here: they could be negative (corresponding to
      a positive value in `future_covariates_lags`), zero, or positive (corresponding to
      a negative value in `future_covariates_lags`). With that being said, the relationship
      `min_lag <= max_lag` always holds.
  
      Consequently, we need to consider three scenarios when finding feature times
      for `future_covariates`:
          1. Both `min_lag` and `max_lag` are positive, which indicates that all of
          the lag values in `future_covariates_lags` are negative (i.e. only values before
          time `t` are used to create a feature from time `t`). In this case, `min_lag`
          and `max_lag` correspond to the smallest magnitude and largest magnitude *negative*
          lags in `future_covariates_lags` respectively. This means we *can* create features for
          times that extend beyond the end of `future_covariates`; additionally, we're unable
          to create features for the first `min_lag` times (see docstring for `get_feature_times_past`).
          2. Both `min_lag` and `max_lag` are non-positive. In this case, `abs(min_lag)` and `abs(max_lag)`
          correspond to the largest and smallest magnitude lags in `future_covariates_lags` respectively;
          note that, somewhat confusingly, `abs(max_lag) <= abs(min_lag)` here. This means that we *can* create f
          features for times that occur before the start of `future_covariates`; the reasoning for this is
          basically the inverse of Case 1 (i.e. we only need to know the values from times `t + abs(max_lag)`
          to `t + abs(min_lag)` to create a feature for time `t`). Additionally, we're unable to create features
          for the last `abs(min_lag)` times in the series, since these times do not have `abs(min_lag)` values
          after them.
          3. `min_lag` is non-positive (i.e. zero or negative), but `max_lag` is positive. In this case,
          `abs(min_lag)` is the magnitude of the largest *non-negative* lag value in `future_covariates_lags`
          and `max_lag` is the largest *negative* lag value in `future_covariates_lags`. This means that we
          *cannot* create features for times that occur before the start of `future_covariates`, nor for
          times that occur after the end of `future_covariates`; this is because we must have access to
          both times before *and* after time `t` to create a feature for this time, which clearly can't
          be acieved for times extending before the start or after the end of the series. Moreover,
          we must exclude the first `max_lag` times and the last `abs(min_lag)` times, since these
          times do not have enough values before or after them respectively.
      """
      times = future_covariates.time_index
      min_lag = -max(future_covariates_lags)
      max_lag = -min(future_covariates_lags)
      # Case 1:
      if (min_lag > 0) and (max_lag > 0):
          # Can create features for times extending after the end of `future_covariates`:
          times = times.union(
              [
                  times[-1] + i * future_covariates.freq
                  for i in range(1, min_lag + 1)
              ]
          )
          # Can't create features for first `max_lag` times in series:
          times = times[max_lag:]
      # Case 2:
      elif (min_lag <= 0) and (max_lag <= 0):
          # Can create features for times before the start of `future_covariates`:
          times = times.union(
              [
                  times[0] - i * future_covariates.freq
                  for i in range(1, abs(max_lag) + 1)
              ]
          )
          # Can't create features for last `abs(min_lag)` times in series:
          times = times[:min_lag] if min_lag != 0 else times
      # Case 3:
      elif (min_lag <= 0) and (max_lag > 0):
          # Can't create features for last `abs(min_lag)` times in series:
          times = times[:min_lag] if min_lag != 0 else times
          # Can't create features for first `max_lag` times in series:
          times = times[max_lag:]
      # Unexpected case:
      else:
          error_msg = (
              "Unexpected `future_covariates_lags` case encountered: "
              "`min_lag` is positive, but `max_lag` is negative. "
              f"Caused by `future_covariates_lags = {future_covariates_lags}`."
          )
          error = ValueError(error_msg)
          raise_log(error, get_logger(__name__))
      return times
  
imports: import warnings
  from itertools import product
  from typing import Optional, Sequence
  import numpy
  import pandas
  import pytest
  from darts import TimeSeries
  from darts import concatenate
  from darts.logging import get_logger, raise_if, raise_if_not, raise_log
  from darts.utils.data.tabularization import create_lagged_component_names, create_lagged_training_data
  from darts.utils.timeseries_generation import linear_timeseries
label_desc: Use image node_id 5 for calling the TestCreateLaggedTrainingData obj's underlying member method code with example usage: obj.get_feature_times_future(future_covariates, future_covariates_lags) and returns: times