Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/Snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ jobs:
with:
dotnet-version: '10.0.x'
project-names: 'Numerics'
# Snapshot workflow appends .<run_number>-dev, so this tracks the next development patch after v2.1.1.
version: '2.1.2'
# Snapshot workflow appends .<run_number>-dev, so this tracks the next development patch after v2.1.2.
version: '2.1.3'
# PR integration already runs the full multi-target test suite.
run-tests: false
nuget-source: 'https://www.hec.usace.army.mil/nexus/repository/consequences-nuget-public/'
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ cff-version: 1.2.0
message: "If you use this software, please cite our article in the Journal of Open Source Software."
type: software
title: "Numerics: A .NET Library for Numerical Computing, Statistical Analysis, and Risk Assessment"
version: "2.1.1"
date-released: "2026-06-17"
version: "2.1.2"
date-released: "2026-07-09"
license: 0BSD
repository-code: "https://github.com/USACE-RMC/Numerics"
url: "https://github.com/USACE-RMC/Numerics"
Expand Down
25 changes: 23 additions & 2 deletions Numerics/Data/Statistics/RunningStatistics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,18 +273,39 @@ public void Push(IList<double> values)
Push(value);
}

/// <summary>
/// Creates a copy of the running statistics.
/// </summary>
/// <returns>A new running statistics instance with the same accumulated state, independent of the original.</returns>
public RunningStatistics Clone()
{
return new RunningStatistics()
{
_n = _n,
_m1 = _m1,
_m2 = _m2,
_m3 = _m3,
_m4 = _m4,
_min = _min,
_max = _max
};
}

/// <summary>
/// Create a new running statistics over the combined samples of two existing running statistics.
/// </summary>
/// <param name="a">The first running statistics.</param>
/// <param name="b">The second running statistics.</param>
/// <returns>A new running statistics instance, independent of both inputs.</returns>
public static RunningStatistics Combine(RunningStatistics a, RunningStatistics b)
{
if (a._n == 0L)
{
return b;
return b.Clone();
}
else if (b._n == 0L)
{
return a;
return a.Clone();
}

long n = a._n + b._n;
Expand Down
31 changes: 18 additions & 13 deletions Numerics/Data/Time Series/Support/Series.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,10 @@ public void Insert(int index, object? item)
public virtual bool Remove(SeriesOrdinate<TIndex, TValue> item)
{
var index = IndexOf(item);
if (_seriesOrdinates.Remove(item) == true)
{
RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
return true;
}
return false;
if (index < 0) return false;
_seriesOrdinates.RemoveAt(index);
RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
return true;
}

/// <inheritdoc/>
Expand All @@ -144,23 +142,30 @@ public void Remove(object? item)
}

/// <inheritdoc/>
/// <remarks>
/// Removes the ordinate at the requested position directly, so when equal-valued
/// ordinates exist elsewhere in the series the element at <paramref name="index"/> is
/// the one removed and reported.
/// </remarks>
public virtual void RemoveAt(int index)
{
Remove(_seriesOrdinates[index]);
var item = _seriesOrdinates[index];
_seriesOrdinates.RemoveAt(index);
RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
}

/// <summary>
/// Remove all elements from the collection.
/// </summary>
/// <remarks>
/// Clears the backing list in one operation and raises a single reset event. The former
/// element-by-element removal cost two full equality scans per element, which made
/// clearing a large series O(n²).
/// </remarks>
public void Clear()
{
bool suppress = SuppressCollectionChanged;
SuppressCollectionChanged = true;
for (int i = _seriesOrdinates.Count - 1; i >= 0; i--)
Remove(_seriesOrdinates[i]);
SuppressCollectionChanged = false;
_seriesOrdinates.Clear();
RaiseCollectionChangedReset();
SuppressCollectionChanged = suppress;
}

/// <inheritdoc/>
Expand Down
Loading
Loading