Skip to content

Commit

Permalink
Adding exponential decay logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton Ragot committed Jan 4, 2024
1 parent 35ac768 commit 5668c2e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
15 changes: 11 additions & 4 deletions darts/utils/data/tabularization.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from darts.logging import get_logger, raise_if, raise_if_not, raise_log
from darts.timeseries import TimeSeries
from darts.utils.utils import get_single_series, series2seq
from darts.utils.timeseries_generation import constant_timeseries, linear_timeseries
from darts.utils.timeseries_generation import constant_timeseries, linear_timeseries, exponential_timeseries

logger = get_logger(__name__)

Expand Down Expand Up @@ -326,12 +326,19 @@ def create_lagged_data(
times.append(times_i)

if sample_weight:
weights = None
if sample_weight == 'equal':
weights = constant_timeseries(1, start=times_i[0], end=times_i[-1], freq=times_i.freq).values()
sample_weights.append(weights)
elif sample_weight == 'linear_decay':
weights = linear_timeseries(start=times_i[0], end=times_i[-1], freq=times_i.freq).values()
sample_weights.append(weights)
elif sample_weight == 'exponential_decay':
weights = exponential_timeseries(start=times_i[0], end=times_i[-1], freq=times_i.freq).values()
else:
raise ValueError(f"sample_weight {sample_weight} is not supported.")

sample_weights.append(weights)

# if instance of TimeSeries, convert to np.ndarray and append

if concatenate:
X = np.concatenate(X, axis=0)
Expand Down Expand Up @@ -596,7 +603,7 @@ def create_lagged_prediction_data(
If the provided series do not share the same type of `time_index` (e.g. `target_series` uses a
pd.RangeIndex, but `future_covariates` uses a `pd.DatetimeIndex`).
"""
X, _, times, _ = create_lagged_data(
X, _, times, _, _ = create_lagged_data(
target_series=target_series,
past_covariates=past_covariates,
future_covariates=future_covariates,
Expand Down
58 changes: 58 additions & 0 deletions darts/utils/timeseries_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,64 @@ def linear_timeseries(
)


def exponential_timeseries(
start_value: float = 1,
end_value: float = 0,
start: Optional[Union[pd.Timestamp, int]] = pd.Timestamp("2000-01-01"),
end: Optional[Union[pd.Timestamp, int]] = None,
length: Optional[int] = None,
freq: Union[str, int] = None,
column_name: Optional[str] = "exponential",
dtype: np.dtype = np.float64,
decay_rate:int = 10,
) -> TimeSeries:
"""
Creates a univariate TimeSeries with a starting value of `start_value` that increases linearly such that
it takes on the value `end_value` at the last entry of the TimeSeries. This means that
the difference between two adjacent entries will be equal to
(`end_value` - `start_value`) / (`length` - 1).
Parameters
----------
start_value
The value of the first entry in the TimeSeries.
end_value
The value of the last entry in the TimeSeries.
start
The start of the returned TimeSeries' index. If a pandas Timestamp is passed, the TimeSeries will have a pandas
DatetimeIndex. If an integer is passed, the TimeSeries will have a pandas RangeIndex index. Works only with
either `length` or `end`.
end
Optionally, the end of the returned index. Works only with either `start` or `length`. If `start` is
set, `end` must be of same type as `start`. Else, it can be either a pandas Timestamp or an integer.
length
Optionally, the length of the returned index. Works only with either `start` or `end`.
freq
The time difference between two adjacent entries in the returned index. In case `start` is a timestamp,
a DateOffset alias is expected; see
`docs <https://pandas.pydata.org/pandas-docs/stable/user_guide/TimeSeries.html#dateoffset-objects>`_.
By default, "D" (daily) is used.
If `start` is an integer, `freq` will be interpreted as the step size in the underlying RangeIndex.
The freq is optional for generating an integer index (if not specified, 1 is used).
column_name
Optionally, the name of the value column for the returned TimeSeries
dtype
The desired NumPy dtype (np.float32 or np.float64) for the resulting series
Returns
-------
TimeSeries
A exponentially decreasing TimeSeries created as indicated above.
"""

index = generate_index(start=start, end=end, freq=freq, length=length)
time_steps = np.linspace(start_value, end_value, len(index), dtype=dtype)
values = np.exp(-decay_rate * (1 - time_steps))
return TimeSeries.from_times_and_values(
index, values, freq=freq, columns=pd.Index([column_name])
)


def sine_timeseries(
value_frequency: float = 0.1,
value_amplitude: float = 1.0,
Expand Down

0 comments on commit 5668c2e

Please sign in to comment.