From c19293ef7cf47a844314f4d7da5189f0d76236cc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 2 Jul 2025 16:05:58 +0000 Subject: [PATCH 1/5] Initial plan From 7280bc2e9dd8395b41080f077b502d7042b3a3cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 2 Jul 2025 16:10:09 +0000 Subject: [PATCH 2/5] Initial exploration and analysis complete Co-authored-by: JanDotNet <21179870+JanDotNet@users.noreply.github.com> --- .../Thinksharp.TimeFlow.xml | 962 ++++++++++++++++++ 1 file changed, 962 insertions(+) create mode 100644 Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml diff --git a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml new file mode 100644 index 0000000..9cbed87 --- /dev/null +++ b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml @@ -0,0 +1,962 @@ + + + + Thinksharp.TimeFlow + + + + + Adds the right to the left value. Null values results in null. + + + + + Adds the right to the left value. Null values will be replaced with 0. + + + + + Subtracts the left from the right value. Null values results in null (null - 1 => null). + + + + + Subtracts the left from the right value. Null values will be replaced with 0 (null - 1 => -1). + + + + + Subtracts the left from the right value. Null values results in null (null * 1 => null). + + + + + Subtracts the left from the right value. Null values will be replaced with 0 (null * 1 => 0). + + + + + Subtracts the left from the right value. Null values results in null (null / 1 => null). + + + + + Subtracts the left from the right value. Null values will be replaced with 0 (null / r => 0; 1 / null => null). + + + + + Takes always the right value. + + + + + If one value is null, the whole aggregation value becomes null. + + + + + If one value is null, the whole aggregation value becomes zero (0). + + + + + If one value is null, the single value becomes zero (0) and will be considered for aggregation (only relevant for average, min, max). + + + + + If one value is null, the single value will be ignored for aggregation (only relevant for average, min, max). + + + + + Creates an period from 2 time points. + + The first time point. + The second time point. + The period that describes the difference between the 2 specified time points. + + + + Creates an infinite sequence of time points + + The first time point to use. + The time zone to use. + + An infinite sequence of time points + + + + + Creates an infinite sequence of time points + + The first time point to use. + The time zone to use. + + An infinite sequence of time points + + + + + Gets or sets the resample type. + + + + + Gets or sets the behavior for single values within an list of values that are resampled. + + + + + The resample type. + + + + + Resampling considers the absolut period interval. E.g. monthly time series form 01.02.2022 to 01.02.2023 resampled to year results in 2 time points (01.02.2022 - 31.12.2022 and 01.01.2022 to 31.12.2023). + + + + + Resampling considers the relative period interval. E.g. monthly time series form 01.02.2022 to 01.02.2023 resampled to year results in 1 time points (01.02.2022 - 01.02.2023). + + + + + A time frame is a collection of named time series with the same frequency that can be processed together. + + + + + Creates a new instance of the time frame. + + + + + Gets the number of time series within the frame. + + + + + Gets the first time point of the frame. + + + + + Gets the last time point of the frame. + + + + + Gets the frequency of all time series within the frame. + + + + + Gets the time zone object of this time frame. + + + + + Enumerates all time points of the frame. + + + An Enumeration of all time points. + + + + + Enumerates all time points of the frame. + + + An Enumeration of all time points. + + + + + Enumerates all names of the frame. + + + An enumeration of all names. + + + + + Adds a time series with the specified name to the frame. + Note that the frequency of the time series must be equal to the frequency of the frame. + + + The name to use for the time series. + + + The time series to add. + + + + + Removes the time series with the specified name from the frame. + + + The name of the time series to remove. + + + + + Creates a copy of the TimeFrame. + + + The copy of the time frame. + + + + + Resamples all time series within the frame to the specified period. + + + The period. + + + The aggregation type used for all time series. + + + The to use. + + + + + Resamples all time series within the frame to the specified period. + + + The period. + + + The aggregation type used for all time series. + + + + + Resamples all time series within the frame to the specified period using the specified aggregation types. + + + The period. + + + A dictionary containing one aggregation type for each time series name. + + + The to use. + + + + + Resamples all time series within the frame to the specified period using the specified aggregation types. + + + The period. + + + A dictionary containing one aggregation type for each time series name. + + + + + Adds a period to the specified time point considering the frequency and the time zone of the current time frame. + + + The time point to add a period to. + + A new time point. + + + + + Returns a new time frame with the specified time series. + + + The names of the time series to get. + + + A new time frame with the specified time series. + + + + + Gets or sets the time series with the specified name. + + + The name of the time series to get. + + + The time series with the specified name. + + + + + Gets the value of the time series with the specified name for the specified time point. + + + The name of the time series to get the value for. + + + The time to get the value for. + + + The value of the time series with the specified name for the specified time point. + + + + + A time series holds a list of time point / value pairs. + Time points are represented as DateTimeOffsets, values as nullable decimals. + The time span between two time points (the Frequency) is always identical for the whole time series. + + + + + The factory contains methods for creating time series object. IT can be extended by custom extension methods for the interface. + + + + + The settings object can be used to configure the time flow framework. + + + + + Gets the time zone object of this time series. + + + + + Gets the value of the time series. + + + + + Gets the time points of the time series. + + + + + Gets the frequency of this time series. + + + + + Adds a period to the specified time point considering the frequency and the time zone of the current time frame. + + + The time point to add a period to. + + A new time point. + + + + + Returns a new time series where all values are mapped using the specified mapping function. + + + The mapping function to use. + + + A new date time series where all values are mapped using the specified mapping function. + + + + + Returns a new date time series where all values are mapped using the specified mapping function whereas null values + remain as null values. + + + The mapping function to use for mapping non-nullable values. + + + A new date time series where all values are mapped using the specified mapping function whereas null values + remain as null values. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + The first value of the aggregation function is from this time series, the second value from the passed one. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + 1. value: Timestamp of the time point to aggregate + 2. value: Value of the first time series. + 3. value: Value of the second time series. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The join operation to use. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + The first value of the aggregation function is from this time series, the second value from the passed one. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + 1. value: Timestamp of the time point to aggregate + 2. value: Value of the first time series. + 3. value: Value of the second time series. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The first time series to join. + + + The second time series to join. + + + The aggregation function to combine values from 3 equal time points. + The first value of the aggregation function is from this time series, the second value from ts1 and the third from + ts2. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The first time series to join. + + + The second time series to join. + + + The aggregation function to combine values from 2 equal time points. + 1. value: Timestamp of the time point to aggregate + 2. value: Value of the first time series. + 3. value: Value of the second time series. + 4. value: Value of the third time series. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The first time series to join. + + + The second time series to join. + + + The third time series to join. + + + The aggregation function to combine values from 4 equal time points. + The first value of the aggregation function is from this time series, the second value from ts1 and the third from + ts2 and the fourth from ts3. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The first time series to join. + + + The second time series to join. + + + The third time series to join. + + + The aggregation function to combine values from 2 equal time points. + 1. value: Timestamp of the time point to aggregate + 2. value: Value of the first time series. + 3. value: Value of the second time series. + 4. value: Value of the third time series. + 5. value: Value of the 4th time series. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Joins the specified time series to the this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The join operation to use. + + + A new time series with the same time points as this one but with values produced by the join. + + + + + Creates a new time series with changed frequency. + + + The new frequency. + + + The aggregation type to use for up/down sampling + + + The resample options to use. + + + A new time series with the new frequency. + + + + + Creates a new time series with changed frequency. + + + The new frequency. + + + The aggregation type to use for up/down sampling + + + A new time series with the new frequency. + + + + + Creates a new time series that contains only time points for the specified day. + If the day is not part of this time series, an empty day will be returned. + + + The date to get the new time series for. + + + A new time series that contains only time points for the specified day. + + + + + Creates a new time series that contains only time points for the specified time range. + Time points within the time range that are not part of the time series are not generated. + + + The including start time. + + + The including end time. + + + A new time series that contains only time points for the specified range. + + + + + Creates a new time series that contains only time points for the specified range. + + + The zero based start index. + + + The number of time points to get. + + + A new time series that contains only time points for the specified range. + + + + + Creates a new time series where leading and trailing time points with specified values are dropped. + + + Specifies if leading time points should be dropped. Default: true. + + + Specifies if trailing time points should be dropped. Default: true. + + + The value to trim. + + + A new time series where leading and trailing time points with specified values are dropped. + + + + + Shifts all time point of the time series by the specified time period (adds the period to the time points). + + + The period to use for shift. + + A new time series that's time points has been shifted by the specified period. + + + + + Shifts all time point of the time series by the specified time period (subtracts the period from the time points). + + + The period to use for shift. + + A new time series that's time points has been shifted by the specified period. + + + + + Creates an empty time series. + + + + + + + Creates a new time series with N constant values. + + + An enumerable of time point / value pairs to create the time series for. + NOTE: The period between the time points must be equal! + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with N constant values. + + + + + Creates a new time series with N constant values. + + + The constant value to use. + + + The first time point of the time series. + + + The number of time points to generate. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with N constant values. + + + + + Creates a new time series with the specified values. + + + The values to use. + + + The first time point of the time series. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the specified values. + + + + + Creates a new time series with the specified values. + + + The values to use. + + + The first time point of the time series. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the specified values. + + + + + Creates a new time series with N constant values. + + + The constant value to use. + + + The first time point of the time series. + + + The number of time points to generate. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with N constant values. + + + + + Creates a new time series with constant values between a specified time range. + + + The constant value to use. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with N constant values. + + + + + Creates a new time series with constant values between a specified time range. + + + The constant value to use. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use for generation. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with N constant values. + + + + + Creates a new time series with generated values. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use for generation. + + + Generator to generate the values based on the time point. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + + Creates a new time series with generated values. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use for generation. + + + Generator to generate the values based on the time point. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + + Creates a new time series for the specified dictionary. + The times series starts by the first and ends with the last time time point in the dictionary. + + + The dictionary that contains the time points to use. + + + The frequency to use. Note that the frequency have to match the time points in the dictionary. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + + Creates a new time series for the specified dictionary. + The times series starts by the first and ends with the last time time point in the dictionary. + + + The dictionary that contains the time points to use. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use. Note that the frequency have to match the time points in the dictionary. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + + Creates a new time series for the specified dictionary. + The times series starts by the first and ends with the last time time point in the dictionary. + + + The dictionary that contains the time points to use. + + + The frequency to use. Note that the frequency have to match the time points in the dictionary. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + + Creates a new time series for the specified dictionary. + The times series starts by the first and ends with the last time time point in the dictionary. + + + The dictionary that contains the time points to use. + + + The first time point of the time series. + + + The last time point of the time series. + + + The frequency to use. Note that the frequency have to match the time points in the dictionary. + + + The time zone to use. (Default: 'W. Europe Standard Time') + + + A new time series with the generated values. + + + + From c14a0cee5ae0955e4021a713408069b78023511b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 2 Jul 2025 16:14:37 +0000 Subject: [PATCH 3/5] Implement inPlace functionality for Apply and ApplyValues methods Co-authored-by: JanDotNet <21179870+JanDotNet@users.noreply.github.com> --- .../Thinksharp.TimeFlow.xml | 55 ++++++++ Thinksharp.TimeFlow/IndexedSeries.cs | 123 ++++++++++++++++-- Thinksharp.TimeFlow/TimeSeries.cs | 74 ++++++++++- 3 files changed, 241 insertions(+), 11 deletions(-) diff --git a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml index 9cbed87..0026b26 100644 --- a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml +++ b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml @@ -4,6 +4,31 @@ Thinksharp.TimeFlow + + + Enables mutation for in-place operations. Should only be used by derived classes during controlled mutations. + + + + + Disables mutation after in-place operations complete. + + + + + Updates the internal data structures during in-place operations. + + + + + Updates the sorted values from the dictionary during in-place operations. + + + + + Updates Start, End, and IsEmpty properties. + + Adds the right to the left value. Null values results in null. @@ -363,6 +388,21 @@ A new date time series where all values are mapped using the specified mapping function. + + + Maps all values using the specified mapping function. + + + The mapping function to use. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series where all values are mapped using the specified mapping function. + If inPlace is true, returns this instance; otherwise returns a new instance. + + Returns a new date time series where all values are mapped using the specified mapping function whereas null values @@ -376,6 +416,21 @@ remain as null values. + + + Maps all values using the specified mapping function whereas null values remain as null values. + + + The mapping function to use for mapping non-nullable values. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series where all values are mapped using the specified mapping function whereas null values + remain as null values. If inPlace is true, returns this instance; otherwise returns a new instance. + + Joins the specified time series to the this time series using the specified aggregation function to combine the diff --git a/Thinksharp.TimeFlow/IndexedSeries.cs b/Thinksharp.TimeFlow/IndexedSeries.cs index eeca4fe..9d0a082 100644 --- a/Thinksharp.TimeFlow/IndexedSeries.cs +++ b/Thinksharp.TimeFlow/IndexedSeries.cs @@ -9,6 +9,8 @@ public abstract class IndexedSeries : IReadOnlyList seriesDictionary = new Dictionary(); protected readonly IList> sortedValues = new List>(); + + private bool allowMutation = false; protected IndexedSeries(IEnumerable> sortedSeries) { @@ -25,28 +27,35 @@ protected IndexedSeries(IEnumerable> sortedSerie if (this.sortedValues.Count > 0) { - this.Start = this.sortedValues.First().Key; - this.End = this.sortedValues.Last().Key; + _start = this.sortedValues.First().Key; + _end = this.sortedValues.Last().Key; } else { - this.Start = default(TKey); - this.End = default(TKey); + _start = default(TKey); + _end = default(TKey); } - this.IsEmpty = this.sortedValues.Count == 0; + _isEmpty = this.sortedValues.Count == 0; } public TValue this[TKey key] { get => this.seriesDictionary.TryGetValue(key, out var value) ? value : default(TValue); - set => throw new NotSupportedException($"IT is not allowed to change {nameof(IndexedSeries)} because it is an immutable data structure"); + set + { + if (!allowMutation) + throw new NotSupportedException($"IT is not allowed to change {nameof(IndexedSeries)} because it is an immutable data structure"); + + this.seriesDictionary[key] = value; + UpdateSortedValues(); + } } public IndexedSeriesItem this[int index] => sortedValues[index]; - public TKey Start { get; } - public TKey End { get; } - public bool IsEmpty { get; } + public TKey Start => _start; + public TKey End => _end; + public bool IsEmpty => _isEmpty; public int Count => this.sortedValues.Count; public IEnumerable Keys => this.seriesDictionary.Keys; @@ -60,5 +69,101 @@ public TValue this[TKey key] public bool TryGetValue(TKey key, out TValue value) => this.seriesDictionary.TryGetValue(key, out value); IEnumerator IEnumerable.GetEnumerator() => this.sortedValues.GetEnumerator(); + + /// + /// Enables mutation for in-place operations. Should only be used by derived classes during controlled mutations. + /// + protected void EnableMutation() + { + allowMutation = true; + } + + /// + /// Disables mutation after in-place operations complete. + /// + protected void DisableMutation() + { + allowMutation = false; + } + + /// + /// Updates the internal data structures during in-place operations. + /// + protected void UpdateInPlace(IEnumerable> newSortedSeries) + { + if (!allowMutation) + throw new InvalidOperationException("Mutation is not enabled. Call EnableMutation() first."); + + this.sortedValues.Clear(); + this.seriesDictionary.Clear(); + + if (newSortedSeries is IList> sortedSeriesList) + { + foreach (var item in sortedSeriesList) + { + this.sortedValues.Add(item); + } + } + else + { + foreach (var item in newSortedSeries) + { + this.sortedValues.Add(item); + } + } + + foreach (var item in this.sortedValues) + { + this.seriesDictionary[item.Key] = item.Value; + } + + UpdateProperties(); + } + + /// + /// Updates the sorted values from the dictionary during in-place operations. + /// + private void UpdateSortedValues() + { + this.sortedValues.Clear(); + foreach (var kvp in this.seriesDictionary.OrderBy(x => x.Key)) + { + this.sortedValues.Add(new IndexedSeriesItem(kvp.Key, kvp.Value)); + } + UpdateProperties(); + } + + /// + /// Updates Start, End, and IsEmpty properties. + /// + private void UpdateProperties() + { + if (this.sortedValues.Count > 0) + { + SetStart(this.sortedValues.First().Key); + SetEnd(this.sortedValues.Last().Key); + } + else + { + SetStart(default(TKey)); + SetEnd(default(TKey)); + } + + SetIsEmpty(this.sortedValues.Count == 0); + } + + // These methods allow updating the readonly properties during in-place operations + private void SetStart(TKey value) => SetProperty(ref _start, value); + private void SetEnd(TKey value) => SetProperty(ref _end, value); + private void SetIsEmpty(bool value) => SetProperty(ref _isEmpty, value); + + private void SetProperty(ref T field, T value) + { + field = value; + } + + private TKey _start; + private TKey _end; + private bool _isEmpty; } } \ No newline at end of file diff --git a/Thinksharp.TimeFlow/TimeSeries.cs b/Thinksharp.TimeFlow/TimeSeries.cs index ae127ef..125ffab 100644 --- a/Thinksharp.TimeFlow/TimeSeries.cs +++ b/Thinksharp.TimeFlow/TimeSeries.cs @@ -72,7 +72,42 @@ internal TimeSeries(IEnumerable> sor /// public TimeSeries Apply(Func func) { - return new TimeSeries(this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, func(x.Value))), this.Frequency, this.TimeZone); + return Apply(func, inPlace: false); + } + + /// + /// Maps all values using the specified mapping function. + /// + /// + /// The mapping function to use. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series where all values are mapped using the specified mapping function. + /// If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries Apply(Func func, bool inPlace = false) + { + if (inPlace) + { + this.EnableMutation(); + try + { + var newSortedSeries = this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, func(x.Value))).ToList(); + this.UpdateInPlace(newSortedSeries); + return this; + } + finally + { + this.DisableMutation(); + } + } + else + { + return new TimeSeries(this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, func(x.Value))), this.Frequency, this.TimeZone); + } } /// @@ -88,7 +123,42 @@ public TimeSeries Apply(Func func) /// public TimeSeries ApplyValues(Func func) { - return new TimeSeries(this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, x.Value.HasValue ? (decimal?)func(x.Value.Value) : null)), this.Frequency, this.TimeZone); + return ApplyValues(func, inPlace: false); + } + + /// + /// Maps all values using the specified mapping function whereas null values remain as null values. + /// + /// + /// The mapping function to use for mapping non-nullable values. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series where all values are mapped using the specified mapping function whereas null values + /// remain as null values. If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries ApplyValues(Func func, bool inPlace = false) + { + if (inPlace) + { + this.EnableMutation(); + try + { + var newSortedSeries = this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, x.Value.HasValue ? (decimal?)func(x.Value.Value) : null)).ToList(); + this.UpdateInPlace(newSortedSeries); + return this; + } + finally + { + this.DisableMutation(); + } + } + else + { + return new TimeSeries(this.sortedValues.Select(x => new IndexedSeriesItem(x.Key, x.Value.HasValue ? (decimal?)func(x.Value.Value) : null)), this.Frequency, this.TimeZone); + } } /// From 4a74eb3a96f8d8c63e60523358e5e8225a46a95f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 2 Jul 2025 16:21:06 +0000 Subject: [PATCH 4/5] Complete inPlace functionality implementation with comprehensive testing Co-authored-by: JanDotNet <21179870+JanDotNet@users.noreply.github.com> --- .../TimeSeriesInPlaceTest.cs | 236 +++++++++++++++ .../Thinksharp.TimeFlow.xml | 135 +++++++++ Thinksharp.TimeFlow/TimeSeries.cs | 270 +++++++++++++++++- 3 files changed, 627 insertions(+), 14 deletions(-) create mode 100644 Thinksharp.TimeFlow.Test/TimeSeriesInPlaceTest.cs diff --git a/Thinksharp.TimeFlow.Test/TimeSeriesInPlaceTest.cs b/Thinksharp.TimeFlow.Test/TimeSeriesInPlaceTest.cs new file mode 100644 index 0000000..28e4679 --- /dev/null +++ b/Thinksharp.TimeFlow.Test/TimeSeriesInPlaceTest.cs @@ -0,0 +1,236 @@ +namespace Thinksharp.TimeFlow +{ + using System; + using System.Linq; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TimeSeriesInPlaceTest + { + [TestMethod] + public void TestApply_InPlace_ModifiesOriginalInstance() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.Apply(x => x * 2, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts.All(x => x.Value == 20), "All values should be doubled"); + } + + [TestMethod] + public void TestApply_InPlace_False_CreatesNewInstance() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.Apply(x => x * 2, inPlace: false); + + // Assert + Assert.AreNotSame(originalRef, result, "Should return a different instance"); + Assert.IsTrue(ts.All(x => x.Value == 10), "Original should be unchanged"); + Assert.IsTrue(result.All(x => x.Value == 20), "Result should have doubled values"); + } + + [TestMethod] + public void TestApply_DefaultBehavior_CreatesNewInstance() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.Apply(x => x * 2); // No inPlace parameter + + // Assert + Assert.AreNotSame(originalRef, result, "Should return a different instance by default"); + Assert.IsTrue(ts.All(x => x.Value == 10), "Original should be unchanged"); + Assert.IsTrue(result.All(x => x.Value == 20), "Result should have doubled values"); + } + + [TestMethod] + public void TestApplyValues_InPlace_ModifiesOriginalInstance() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.ApplyValues(x => x + 5, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts.All(x => x.Value == 15), "All values should be incremented by 5"); + } + + [TestMethod] + public void TestJoinLeft_InPlace_ModifiesOriginalInstance() + { + // Arrange + var ts1 = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var ts2 = TimeSeries.Factory.FromValue(3, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts1; + + // Act + var result = ts1.JoinLeft(ts2, (left, right) => left + right, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts1.All(x => x.Value == 13), "All values should be sum of left and right"); + } + + [TestMethod] + public void TestJoinLeft_WithJoinOperation_InPlace_ModifiesOriginalInstance() + { + // Arrange + var ts1 = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var ts2 = TimeSeries.Factory.FromValue(2, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts1; + + // Act + var result = ts1.JoinLeft(ts2, JoinOperation.Multiply, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts1.All(x => x.Value == 20), "All values should be multiplied"); + } + + [TestMethod] + public void TestSlice_InPlace_ModifiesOriginalInstance() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 10, Period.Day); + var originalRef = ts; + var originalCount = ts.Count; + + // Act + var result = ts.Slice(2, 5, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.AreEqual(5, ts.Count, "Should have 5 elements after slice"); + Assert.AreNotEqual(originalCount, ts.Count, "Count should have changed"); + Assert.AreEqual(new DateTime(2023, 1, 3), ts.Start.DateTime, "Start should be third day"); + Assert.AreEqual(new DateTime(2023, 1, 7), ts.End.DateTime, "End should be seventh day"); + } + + [TestMethod] + public void TestConvenienceMethods_AddInPlace() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.AddInPlace(5); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts.All(x => x.Value == 15), "All values should be incremented by 5"); + } + + [TestMethod] + public void TestConvenienceMethods_MultiplyInPlace() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.MultiplyInPlace(3); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts.All(x => x.Value == 30), "All values should be multiplied by 3"); + } + + [TestMethod] + public void TestConvenienceMethods_MethodChaining() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts; + + // Act + var result = ts.AddInPlace(5).MultiplyInPlace(2).SubtractInPlace(10); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts.All(x => x.Value == 20), "Should apply all operations: (10+5)*2-10 = 20"); + } + + [TestMethod] + public void TestConvenienceMethods_AddInPlace_WithTimeSeries() + { + // Arrange + var ts1 = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Day); + var ts2 = TimeSeries.Factory.FromValue(7, new DateTime(2023, 1, 1), 5, Period.Day); + var originalRef = ts1; + + // Act + var result = ts1.AddInPlace(ts2); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.IsTrue(ts1.All(x => x.Value == 17), "All values should be sum: 10 + 7 = 17"); + } + + [TestMethod] + public void TestInPlace_WithNullValues() + { + // Arrange + var values = new decimal?[] { 10, null, 20, null, 30 }; + var ts = TimeSeries.Factory.FromValues(values, new DateTime(2023, 1, 1), Period.Day); + var originalRef = ts; + + // Act + var result = ts.Apply(x => x.HasValue ? x * 2 : null, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.AreEqual(20, ts[new DateTimeOffset(new DateTime(2023, 1, 1))]); + Assert.AreEqual(null, ts[new DateTimeOffset(new DateTime(2023, 1, 2))]); + Assert.AreEqual(40, ts[new DateTimeOffset(new DateTime(2023, 1, 3))]); + Assert.AreEqual(null, ts[new DateTimeOffset(new DateTime(2023, 1, 4))]); + Assert.AreEqual(60, ts[new DateTimeOffset(new DateTime(2023, 1, 5))]); + } + + [TestMethod] + public void TestInPlace_PreservesFrequencyAndTimeZone() + { + // Arrange + var ts = TimeSeries.Factory.FromValue(10, new DateTime(2023, 1, 1), 5, Period.Hour); + var originalFrequency = ts.Frequency; + var originalTimeZone = ts.TimeZone; + + // Act + ts.Apply(x => x * 2, inPlace: true); + + // Assert + Assert.AreEqual(originalFrequency, ts.Frequency, "Frequency should be preserved"); + Assert.AreEqual(originalTimeZone, ts.TimeZone, "TimeZone should be preserved"); + } + + [TestMethod] + public void TestInPlace_EmptyTimeSeries() + { + // Arrange + var ts = TimeSeries.Factory.Empty(); + var originalRef = ts; + + // Act + var result = ts.Apply(x => x * 2, inPlace: true); + + // Assert + Assert.AreSame(originalRef, result, "Should return the same instance"); + Assert.AreEqual(0, ts.Count, "Empty time series should remain empty"); + Assert.IsTrue(ts.IsEmpty, "Should still be empty"); + } + } +} \ No newline at end of file diff --git a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml index 0026b26..3fb4527 100644 --- a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml +++ b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml @@ -447,6 +447,26 @@ A new time series with the same time points as this one but with values produced by the join. + + + Joins the specified time series to this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + The first value of the aggregation function is from this time series, the second value from the passed one. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series with the same time points as this one but with values produced by the join. + If inPlace is true, returns this instance; otherwise returns a new instance. + + Joins the specified time series to the this time series using the specified aggregation function to combine the @@ -465,6 +485,28 @@ A new time series with the same time points as this one but with values produced by the join. + + + Joins the specified time series to this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The aggregation function to combine values from 2 equal time points. + 1. value: Timestamp of the time point to aggregate + 2. value: Value of the first time series. + 3. value: Value of the second time series. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series with the same time points as this one but with values produced by the join. + If inPlace is true, returns this instance; otherwise returns a new instance. + + Joins the specified time series to the this time series using the specified aggregation function to combine the @@ -480,6 +522,25 @@ A new time series with the same time points as this one but with values produced by the join. + + + Joins the specified time series to this time series using the specified aggregation function to combine the + values. + + + The time series to join. + + + The join operation to use. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series with the same time points as this one but with values produced by the join. + If inPlace is true, returns this instance; otherwise returns a new instance. + + Joins the specified time series to the this time series using the specified aggregation function to combine the @@ -692,6 +753,24 @@ A new time series that contains only time points for the specified range. + + + Creates a time series that contains only time points for the specified range. + + + The zero based start index. + + + The number of time points to get. + + + If true, modifies this time series instance instead of creating a new one. Default is false. + + + A time series that contains only time points for the specified range. + If inPlace is true, returns this instance; otherwise returns a new instance. + + Creates a new time series where leading and trailing time points with specified values are dropped. @@ -729,6 +808,62 @@ A new time series that's time points has been shifted by the specified period. + + + Adds a scalar value to all elements in place. + + The value to add. + This TimeSeries instance for method chaining. + + + + Subtracts a scalar value from all elements in place. + + The value to subtract. + This TimeSeries instance for method chaining. + + + + Multiplies all elements by a scalar value in place. + + The value to multiply by. + This TimeSeries instance for method chaining. + + + + Divides all elements by a scalar value in place. + + The value to divide by. + This TimeSeries instance for method chaining. + + + + Adds another time series to this one in place using JoinLeft. + + The time series to add. + This TimeSeries instance for method chaining. + + + + Subtracts another time series from this one in place using JoinLeft. + + The time series to subtract. + This TimeSeries instance for method chaining. + + + + Multiplies this time series by another one in place using JoinLeft. + + The time series to multiply by. + This TimeSeries instance for method chaining. + + + + Divides this time series by another one in place using JoinLeft. + + The time series to divide by. + This TimeSeries instance for method chaining. + Creates an empty time series. diff --git a/Thinksharp.TimeFlow/TimeSeries.cs b/Thinksharp.TimeFlow/TimeSeries.cs index 125ffab..0323ae2 100644 --- a/Thinksharp.TimeFlow/TimeSeries.cs +++ b/Thinksharp.TimeFlow/TimeSeries.cs @@ -176,20 +176,68 @@ public TimeSeries ApplyValues(Func func, bool inPlace = false) /// A new time series with the same time points as this one but with values produced by the join. /// public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func agg) + { + return JoinLeft(dateTimeSeries, agg, inPlace: false); + } + + /// + /// Joins the specified time series to this time series using the specified aggregation function to combine the + /// values. + /// + /// + /// The time series to join. + /// + /// + /// The aggregation function to combine values from 2 equal time points. + /// The first value of the aggregation function is from this time series, the second value from the passed one. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series with the same time points as this one but with values produced by the join. + /// If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func agg, bool inPlace = false) { var freq = EnsureFrequenciesAreCompatible(dateTimeSeries); var tz = EnsureTimeZonesAreCompatible(dateTimeSeries); - var result = new List>(); - foreach (var sortedValue in this.sortedValues) + if (inPlace) { - var leftValue = sortedValue.Value; - var rightValue = dateTimeSeries[sortedValue.Key]; + this.EnableMutation(); + try + { + var result = new List>(); + foreach (var sortedValue in this.sortedValues) + { + var leftValue = sortedValue.Value; + var rightValue = dateTimeSeries[sortedValue.Key]; - result.Add(new IndexedSeriesItem(sortedValue.Key, agg(leftValue, rightValue))); + result.Add(new IndexedSeriesItem(sortedValue.Key, agg(leftValue, rightValue))); + } + + this.UpdateInPlace(result); + return this; + } + finally + { + this.DisableMutation(); + } } + else + { + var result = new List>(); + foreach (var sortedValue in this.sortedValues) + { + var leftValue = sortedValue.Value; + var rightValue = dateTimeSeries[sortedValue.Key]; - return new TimeSeries(result, freq, tz); + result.Add(new IndexedSeriesItem(sortedValue.Key, agg(leftValue, rightValue))); + } + + return new TimeSeries(result, freq, tz); + } } /// @@ -209,20 +257,70 @@ public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func agg) + { + return JoinLeft(dateTimeSeries, agg, inPlace: false); + } + + /// + /// Joins the specified time series to this time series using the specified aggregation function to combine the + /// values. + /// + /// + /// The time series to join. + /// + /// + /// The aggregation function to combine values from 2 equal time points. + /// 1. value: Timestamp of the time point to aggregate + /// 2. value: Value of the first time series. + /// 3. value: Value of the second time series. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series with the same time points as this one but with values produced by the join. + /// If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func agg, bool inPlace = false) { var freq = EnsureFrequenciesAreCompatible(dateTimeSeries); var tz = EnsureTimeZonesAreCompatible(dateTimeSeries); - var result = new List>(); - foreach (var sortedValue in this.sortedValues) + if (inPlace) { - var leftValue = sortedValue.Value; - var rightValue = dateTimeSeries[sortedValue.Key]; + this.EnableMutation(); + try + { + var result = new List>(); + foreach (var sortedValue in this.sortedValues) + { + var leftValue = sortedValue.Value; + var rightValue = dateTimeSeries[sortedValue.Key]; - result.Add(new IndexedSeriesItem(sortedValue.Key, agg(sortedValue.Key, leftValue, rightValue))); + result.Add(new IndexedSeriesItem(sortedValue.Key, agg(sortedValue.Key, leftValue, rightValue))); + } + + this.UpdateInPlace(result); + return this; + } + finally + { + this.DisableMutation(); + } } + else + { + var result = new List>(); + foreach (var sortedValue in this.sortedValues) + { + var leftValue = sortedValue.Value; + var rightValue = dateTimeSeries[sortedValue.Key]; - return new TimeSeries(result, freq, tz); + result.Add(new IndexedSeriesItem(sortedValue.Key, agg(sortedValue.Key, leftValue, rightValue))); + } + + return new TimeSeries(result, freq, tz); + } } /// @@ -240,7 +338,29 @@ public TimeSeries JoinLeft(TimeSeries dateTimeSeries, Func public TimeSeries JoinLeft(TimeSeries dateTimeSeries, JoinOperation op) { - return this.JoinLeft(dateTimeSeries, op.Apply); + return JoinLeft(dateTimeSeries, op, inPlace: false); + } + + /// + /// Joins the specified time series to this time series using the specified aggregation function to combine the + /// values. + /// + /// + /// The time series to join. + /// + /// + /// The join operation to use. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series with the same time points as this one but with values produced by the join. + /// If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries JoinLeft(TimeSeries dateTimeSeries, JoinOperation op, bool inPlace = false) + { + return this.JoinLeft(dateTimeSeries, op.Apply, inPlace); } /// @@ -814,7 +934,45 @@ public TimeSeries Slice(DateTimeOffset timestampFrom, Period period) /// public TimeSeries Slice(int startIndex, int count) { - return new TimeSeries(this.sortedValues.Skip(startIndex).Take(count), this.Frequency, this.TimeZone); + return Slice(startIndex, count, inPlace: false); + } + + /// + /// Creates a time series that contains only time points for the specified range. + /// + /// + /// The zero based start index. + /// + /// + /// The number of time points to get. + /// + /// + /// If true, modifies this time series instance instead of creating a new one. Default is false. + /// + /// + /// A time series that contains only time points for the specified range. + /// If inPlace is true, returns this instance; otherwise returns a new instance. + /// + public TimeSeries Slice(int startIndex, int count, bool inPlace = false) + { + if (inPlace) + { + this.EnableMutation(); + try + { + var slicedData = this.sortedValues.Skip(startIndex).Take(count).ToList(); + this.UpdateInPlace(slicedData); + return this; + } + finally + { + this.DisableMutation(); + } + } + else + { + return new TimeSeries(this.sortedValues.Skip(startIndex).Take(count), this.Frequency, this.TimeZone); + } } /// @@ -1010,6 +1168,90 @@ private TimeZoneInfo EnsureTimeZonesAreCompatible(params TimeSeries[] dateTimeSe return allNonEmpty.FirstOrDefault()?.TimeZone ?? this.TimeZone; } + #region InPlace Convenience Methods + + /// + /// Adds a scalar value to all elements in place. + /// + /// The value to add. + /// This TimeSeries instance for method chaining. + public TimeSeries AddInPlace(decimal value) + { + return this.Apply(x => x + value, inPlace: true); + } + + /// + /// Subtracts a scalar value from all elements in place. + /// + /// The value to subtract. + /// This TimeSeries instance for method chaining. + public TimeSeries SubtractInPlace(decimal value) + { + return this.Apply(x => x - value, inPlace: true); + } + + /// + /// Multiplies all elements by a scalar value in place. + /// + /// The value to multiply by. + /// This TimeSeries instance for method chaining. + public TimeSeries MultiplyInPlace(decimal value) + { + return this.Apply(x => x * value, inPlace: true); + } + + /// + /// Divides all elements by a scalar value in place. + /// + /// The value to divide by. + /// This TimeSeries instance for method chaining. + public TimeSeries DivideInPlace(decimal value) + { + return this.Apply(x => x / value, inPlace: true); + } + + /// + /// Adds another time series to this one in place using JoinLeft. + /// + /// The time series to add. + /// This TimeSeries instance for method chaining. + public TimeSeries AddInPlace(TimeSeries other) + { + return this.JoinLeft(other, JoinOperation.Add, inPlace: true); + } + + /// + /// Subtracts another time series from this one in place using JoinLeft. + /// + /// The time series to subtract. + /// This TimeSeries instance for method chaining. + public TimeSeries SubtractInPlace(TimeSeries other) + { + return this.JoinLeft(other, JoinOperation.Subtract, inPlace: true); + } + + /// + /// Multiplies this time series by another one in place using JoinLeft. + /// + /// The time series to multiply by. + /// This TimeSeries instance for method chaining. + public TimeSeries MultiplyInPlace(TimeSeries other) + { + return this.JoinLeft(other, JoinOperation.Multiply, inPlace: true); + } + + /// + /// Divides this time series by another one in place using JoinLeft. + /// + /// The time series to divide by. + /// This TimeSeries instance for method chaining. + public TimeSeries DivideInPlace(TimeSeries other) + { + return this.JoinLeft(other, JoinOperation.Divide, inPlace: true); + } + + #endregion + #region Operators public static TimeSeries operator +(TimeSeries ts) From 93d3b45aa340baa1eee6e484548ec62b20a5da81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Niklas=20Sch=C3=A4fer?= Date: Thu, 3 Jul 2025 07:53:42 +0200 Subject: [PATCH 5/5] Delete Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml --- .../Thinksharp.TimeFlow.xml | 1152 ----------------- 1 file changed, 1152 deletions(-) delete mode 100644 Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml diff --git a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml b/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml deleted file mode 100644 index 3fb4527..0000000 --- a/Thinksharp.TimeFlow/C:/Users/Tachy/Projects/ThinkSharp/Thinksharp.TimeFlow/Thinksharp.TimeFlow/Thinksharp.TimeFlow.xml +++ /dev/null @@ -1,1152 +0,0 @@ - - - - Thinksharp.TimeFlow - - - - - Enables mutation for in-place operations. Should only be used by derived classes during controlled mutations. - - - - - Disables mutation after in-place operations complete. - - - - - Updates the internal data structures during in-place operations. - - - - - Updates the sorted values from the dictionary during in-place operations. - - - - - Updates Start, End, and IsEmpty properties. - - - - - Adds the right to the left value. Null values results in null. - - - - - Adds the right to the left value. Null values will be replaced with 0. - - - - - Subtracts the left from the right value. Null values results in null (null - 1 => null). - - - - - Subtracts the left from the right value. Null values will be replaced with 0 (null - 1 => -1). - - - - - Subtracts the left from the right value. Null values results in null (null * 1 => null). - - - - - Subtracts the left from the right value. Null values will be replaced with 0 (null * 1 => 0). - - - - - Subtracts the left from the right value. Null values results in null (null / 1 => null). - - - - - Subtracts the left from the right value. Null values will be replaced with 0 (null / r => 0; 1 / null => null). - - - - - Takes always the right value. - - - - - If one value is null, the whole aggregation value becomes null. - - - - - If one value is null, the whole aggregation value becomes zero (0). - - - - - If one value is null, the single value becomes zero (0) and will be considered for aggregation (only relevant for average, min, max). - - - - - If one value is null, the single value will be ignored for aggregation (only relevant for average, min, max). - - - - - Creates an period from 2 time points. - - The first time point. - The second time point. - The period that describes the difference between the 2 specified time points. - - - - Creates an infinite sequence of time points - - The first time point to use. - The time zone to use. - - An infinite sequence of time points - - - - - Creates an infinite sequence of time points - - The first time point to use. - The time zone to use. - - An infinite sequence of time points - - - - - Gets or sets the resample type. - - - - - Gets or sets the behavior for single values within an list of values that are resampled. - - - - - The resample type. - - - - - Resampling considers the absolut period interval. E.g. monthly time series form 01.02.2022 to 01.02.2023 resampled to year results in 2 time points (01.02.2022 - 31.12.2022 and 01.01.2022 to 31.12.2023). - - - - - Resampling considers the relative period interval. E.g. monthly time series form 01.02.2022 to 01.02.2023 resampled to year results in 1 time points (01.02.2022 - 01.02.2023). - - - - - A time frame is a collection of named time series with the same frequency that can be processed together. - - - - - Creates a new instance of the time frame. - - - - - Gets the number of time series within the frame. - - - - - Gets the first time point of the frame. - - - - - Gets the last time point of the frame. - - - - - Gets the frequency of all time series within the frame. - - - - - Gets the time zone object of this time frame. - - - - - Enumerates all time points of the frame. - - - An Enumeration of all time points. - - - - - Enumerates all time points of the frame. - - - An Enumeration of all time points. - - - - - Enumerates all names of the frame. - - - An enumeration of all names. - - - - - Adds a time series with the specified name to the frame. - Note that the frequency of the time series must be equal to the frequency of the frame. - - - The name to use for the time series. - - - The time series to add. - - - - - Removes the time series with the specified name from the frame. - - - The name of the time series to remove. - - - - - Creates a copy of the TimeFrame. - - - The copy of the time frame. - - - - - Resamples all time series within the frame to the specified period. - - - The period. - - - The aggregation type used for all time series. - - - The to use. - - - - - Resamples all time series within the frame to the specified period. - - - The period. - - - The aggregation type used for all time series. - - - - - Resamples all time series within the frame to the specified period using the specified aggregation types. - - - The period. - - - A dictionary containing one aggregation type for each time series name. - - - The to use. - - - - - Resamples all time series within the frame to the specified period using the specified aggregation types. - - - The period. - - - A dictionary containing one aggregation type for each time series name. - - - - - Adds a period to the specified time point considering the frequency and the time zone of the current time frame. - - - The time point to add a period to. - - A new time point. - - - - - Returns a new time frame with the specified time series. - - - The names of the time series to get. - - - A new time frame with the specified time series. - - - - - Gets or sets the time series with the specified name. - - - The name of the time series to get. - - - The time series with the specified name. - - - - - Gets the value of the time series with the specified name for the specified time point. - - - The name of the time series to get the value for. - - - The time to get the value for. - - - The value of the time series with the specified name for the specified time point. - - - - - A time series holds a list of time point / value pairs. - Time points are represented as DateTimeOffsets, values as nullable decimals. - The time span between two time points (the Frequency) is always identical for the whole time series. - - - - - The factory contains methods for creating time series object. IT can be extended by custom extension methods for the interface. - - - - - The settings object can be used to configure the time flow framework. - - - - - Gets the time zone object of this time series. - - - - - Gets the value of the time series. - - - - - Gets the time points of the time series. - - - - - Gets the frequency of this time series. - - - - - Adds a period to the specified time point considering the frequency and the time zone of the current time frame. - - - The time point to add a period to. - - A new time point. - - - - - Returns a new time series where all values are mapped using the specified mapping function. - - - The mapping function to use. - - - A new date time series where all values are mapped using the specified mapping function. - - - - - Maps all values using the specified mapping function. - - - The mapping function to use. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series where all values are mapped using the specified mapping function. - If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Returns a new date time series where all values are mapped using the specified mapping function whereas null values - remain as null values. - - - The mapping function to use for mapping non-nullable values. - - - A new date time series where all values are mapped using the specified mapping function whereas null values - remain as null values. - - - - - Maps all values using the specified mapping function whereas null values remain as null values. - - - The mapping function to use for mapping non-nullable values. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series where all values are mapped using the specified mapping function whereas null values - remain as null values. If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - The first value of the aggregation function is from this time series, the second value from the passed one. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - The first value of the aggregation function is from this time series, the second value from the passed one. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series with the same time points as this one but with values produced by the join. - If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - 1. value: Timestamp of the time point to aggregate - 2. value: Value of the first time series. - 3. value: Value of the second time series. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - 1. value: Timestamp of the time point to aggregate - 2. value: Value of the first time series. - 3. value: Value of the second time series. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series with the same time points as this one but with values produced by the join. - If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The join operation to use. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The join operation to use. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series with the same time points as this one but with values produced by the join. - If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - The first value of the aggregation function is from this time series, the second value from the passed one. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The aggregation function to combine values from 2 equal time points. - 1. value: Timestamp of the time point to aggregate - 2. value: Value of the first time series. - 3. value: Value of the second time series. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The first time series to join. - - - The second time series to join. - - - The aggregation function to combine values from 3 equal time points. - The first value of the aggregation function is from this time series, the second value from ts1 and the third from - ts2. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The first time series to join. - - - The second time series to join. - - - The aggregation function to combine values from 2 equal time points. - 1. value: Timestamp of the time point to aggregate - 2. value: Value of the first time series. - 3. value: Value of the second time series. - 4. value: Value of the third time series. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The first time series to join. - - - The second time series to join. - - - The third time series to join. - - - The aggregation function to combine values from 4 equal time points. - The first value of the aggregation function is from this time series, the second value from ts1 and the third from - ts2 and the fourth from ts3. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The first time series to join. - - - The second time series to join. - - - The third time series to join. - - - The aggregation function to combine values from 2 equal time points. - 1. value: Timestamp of the time point to aggregate - 2. value: Value of the first time series. - 3. value: Value of the second time series. - 4. value: Value of the third time series. - 5. value: Value of the 4th time series. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Joins the specified time series to the this time series using the specified aggregation function to combine the - values. - - - The time series to join. - - - The join operation to use. - - - A new time series with the same time points as this one but with values produced by the join. - - - - - Creates a new time series with changed frequency. - - - The new frequency. - - - The aggregation type to use for up/down sampling - - - The resample options to use. - - - A new time series with the new frequency. - - - - - Creates a new time series with changed frequency. - - - The new frequency. - - - The aggregation type to use for up/down sampling - - - A new time series with the new frequency. - - - - - Creates a new time series that contains only time points for the specified day. - If the day is not part of this time series, an empty day will be returned. - - - The date to get the new time series for. - - - A new time series that contains only time points for the specified day. - - - - - Creates a new time series that contains only time points for the specified time range. - Time points within the time range that are not part of the time series are not generated. - - - The including start time. - - - The including end time. - - - A new time series that contains only time points for the specified range. - - - - - Creates a new time series that contains only time points for the specified range. - - - The zero based start index. - - - The number of time points to get. - - - A new time series that contains only time points for the specified range. - - - - - Creates a time series that contains only time points for the specified range. - - - The zero based start index. - - - The number of time points to get. - - - If true, modifies this time series instance instead of creating a new one. Default is false. - - - A time series that contains only time points for the specified range. - If inPlace is true, returns this instance; otherwise returns a new instance. - - - - - Creates a new time series where leading and trailing time points with specified values are dropped. - - - Specifies if leading time points should be dropped. Default: true. - - - Specifies if trailing time points should be dropped. Default: true. - - - The value to trim. - - - A new time series where leading and trailing time points with specified values are dropped. - - - - - Shifts all time point of the time series by the specified time period (adds the period to the time points). - - - The period to use for shift. - - A new time series that's time points has been shifted by the specified period. - - - - - Shifts all time point of the time series by the specified time period (subtracts the period from the time points). - - - The period to use for shift. - - A new time series that's time points has been shifted by the specified period. - - - - - Adds a scalar value to all elements in place. - - The value to add. - This TimeSeries instance for method chaining. - - - - Subtracts a scalar value from all elements in place. - - The value to subtract. - This TimeSeries instance for method chaining. - - - - Multiplies all elements by a scalar value in place. - - The value to multiply by. - This TimeSeries instance for method chaining. - - - - Divides all elements by a scalar value in place. - - The value to divide by. - This TimeSeries instance for method chaining. - - - - Adds another time series to this one in place using JoinLeft. - - The time series to add. - This TimeSeries instance for method chaining. - - - - Subtracts another time series from this one in place using JoinLeft. - - The time series to subtract. - This TimeSeries instance for method chaining. - - - - Multiplies this time series by another one in place using JoinLeft. - - The time series to multiply by. - This TimeSeries instance for method chaining. - - - - Divides this time series by another one in place using JoinLeft. - - The time series to divide by. - This TimeSeries instance for method chaining. - - - - Creates an empty time series. - - - - - - - Creates a new time series with N constant values. - - - An enumerable of time point / value pairs to create the time series for. - NOTE: The period between the time points must be equal! - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with N constant values. - - - - - Creates a new time series with N constant values. - - - The constant value to use. - - - The first time point of the time series. - - - The number of time points to generate. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with N constant values. - - - - - Creates a new time series with the specified values. - - - The values to use. - - - The first time point of the time series. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the specified values. - - - - - Creates a new time series with the specified values. - - - The values to use. - - - The first time point of the time series. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the specified values. - - - - - Creates a new time series with N constant values. - - - The constant value to use. - - - The first time point of the time series. - - - The number of time points to generate. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with N constant values. - - - - - Creates a new time series with constant values between a specified time range. - - - The constant value to use. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with N constant values. - - - - - Creates a new time series with constant values between a specified time range. - - - The constant value to use. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use for generation. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with N constant values. - - - - - Creates a new time series with generated values. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use for generation. - - - Generator to generate the values based on the time point. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - - - Creates a new time series with generated values. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use for generation. - - - Generator to generate the values based on the time point. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - - - Creates a new time series for the specified dictionary. - The times series starts by the first and ends with the last time time point in the dictionary. - - - The dictionary that contains the time points to use. - - - The frequency to use. Note that the frequency have to match the time points in the dictionary. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - - - Creates a new time series for the specified dictionary. - The times series starts by the first and ends with the last time time point in the dictionary. - - - The dictionary that contains the time points to use. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use. Note that the frequency have to match the time points in the dictionary. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - - - Creates a new time series for the specified dictionary. - The times series starts by the first and ends with the last time time point in the dictionary. - - - The dictionary that contains the time points to use. - - - The frequency to use. Note that the frequency have to match the time points in the dictionary. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - - - Creates a new time series for the specified dictionary. - The times series starts by the first and ends with the last time time point in the dictionary. - - - The dictionary that contains the time points to use. - - - The first time point of the time series. - - - The last time point of the time series. - - - The frequency to use. Note that the frequency have to match the time points in the dictionary. - - - The time zone to use. (Default: 'W. Europe Standard Time') - - - A new time series with the generated values. - - - -