mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-19 11:08:05 +00:00
normalization of methods
This commit is contained in:
@@ -332,7 +332,7 @@ public class HuberTests
|
||||
predicted.Add(now.AddMinutes(i), 100.5); // Small constant error
|
||||
}
|
||||
|
||||
var results = Huber.Calculate(actual, predicted, 3);
|
||||
var results = Huber.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// Error = 0.5, Huber (small error) = 0.5 * 0.5^2 = 0.125
|
||||
@@ -355,7 +355,7 @@ public class HuberTests
|
||||
predicted.Add(DateTime.UtcNow, i);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Huber.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Huber.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -67,7 +67,7 @@ public sealed class Huber : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates Huber Loss for two time series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period, double delta = 1.345)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period, double delta = 1.345)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -127,4 +127,11 @@ public sealed class Huber : BiInputIndicatorBase
|
||||
// Apply rolling mean
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Huber Indicator) Calculate(TSeries actual, TSeries predicted, int period, double delta = 1.345)
|
||||
{
|
||||
var indicator = new Huber(period, delta);
|
||||
TSeries results = Batch(actual, predicted, period, delta);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ public class LogCoshTests
|
||||
iterativeResults[i] = logCoshIterative.Update(actualSeries[i], predictedSeries[i]).Value;
|
||||
}
|
||||
|
||||
var batchResults = LogCosh.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = LogCosh.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(count, batchResults.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
@@ -283,7 +283,7 @@ public class LogCoshTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = LogCosh.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = LogCosh.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
LogCosh.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -332,7 +332,7 @@ public class LogCoshTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => LogCosh.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => LogCosh.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -58,7 +58,7 @@ public sealed class LogCosh : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates LogCosh for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -97,4 +97,11 @@ public sealed class LogCosh : BiInputIndicatorBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, LogCosh Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new LogCosh(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ public class MaapeTests
|
||||
streamingResults[i] = maapeIterative.Update(actualArr[i], predictedArr[i]).Value;
|
||||
}
|
||||
|
||||
var batchResults = Maape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = Maape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(count, batchResults.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
@@ -256,7 +256,7 @@ public class MaapeTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = Maape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = Maape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
Maape.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -305,7 +305,7 @@ public class MaapeTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Maape.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => Maape.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed class Maape : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates Mean Arctangent Absolute Percentage Error for two time series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -116,6 +116,13 @@ public sealed class Maape : BiInputIndicatorBase
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Maape Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Maape(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes arctangent percentage errors.
|
||||
/// </summary>
|
||||
@@ -178,4 +185,4 @@ public sealed class Maape : BiInputIndicatorBase
|
||||
output[i] = absActual > Epsilon ? Math.Atan(absError / absActual) : Math.PI / 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public class MaeTests
|
||||
predicted.Add(now.AddMinutes(i), i * 10 + 5);
|
||||
}
|
||||
|
||||
var results = Mae.Calculate(actual, predicted, 3);
|
||||
var results = Mae.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// All errors are 5, so MAE should be 5
|
||||
@@ -331,7 +331,7 @@ public class MaeTests
|
||||
predicted.Add(DateTime.UtcNow, i);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mae.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Mae.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -45,7 +45,7 @@ public sealed class Mae : BiInputIndicatorBase
|
||||
/// <param name="predicted">Predicted values series</param>
|
||||
/// <param name="period">MAE period</param>
|
||||
/// <returns>MAE series</returns>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -89,4 +89,11 @@ public sealed class Mae : BiInputIndicatorBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mae Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mae(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ public class MapdTests
|
||||
predicted.Add(now.AddMinutes(i), 110);
|
||||
}
|
||||
|
||||
var results = Mapd.Calculate(actual, predicted, 3);
|
||||
var results = Mapd.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// |100-110|/110 * 100 = 9.0909...%
|
||||
@@ -315,7 +315,7 @@ public class MapdTests
|
||||
predicted.Add(DateTime.UtcNow, i + 1);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mapd.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Mapd.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -48,7 +48,7 @@ public sealed class Mapd : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates Mean Absolute Percentage Deviation for two time series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -104,6 +104,13 @@ public sealed class Mapd : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mapd Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mapd(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes MAPD errors (percentage errors divided by predicted).
|
||||
/// </summary>
|
||||
@@ -164,4 +171,4 @@ public sealed class Mapd : BiInputIndicatorBase
|
||||
: 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public class MapeTests
|
||||
predicted.Add(now.AddMinutes(i), 110); // 10% error
|
||||
}
|
||||
|
||||
var results = Mape.Calculate(actual, predicted, 3);
|
||||
var results = Mape.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
Assert.Equal(10.0, results.Last.Value, 10);
|
||||
@@ -330,7 +330,7 @@ public class MapeTests
|
||||
predicted.Add(DateTime.UtcNow, i + 1);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mape.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Mape.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -41,7 +41,7 @@ public sealed class Mape : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates MAPE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -65,4 +65,11 @@ public sealed class Mape : BiInputIndicatorBase
|
||||
ErrorHelpers.ComputePercentageErrors(actual, predicted, percentErrors, Epsilon);
|
||||
ErrorHelpers.ApplyRollingMean(percentErrors, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mape Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mape(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public class MaseTests
|
||||
iterativeResults.Add(maseIterative.Update(actual[i], predicted[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Mase.Calculate(actual, predicted, Period);
|
||||
var batchResults = Mase.Batch(actual, predicted, Period);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -282,7 +282,7 @@ public class MaseTests
|
||||
double[] predictedArr = predictedSeries.Values.ToArray();
|
||||
double[] output = new double[100];
|
||||
|
||||
var tseriesResult = Mase.Calculate(actualSeries, predictedSeries, Period);
|
||||
var tseriesResult = Mase.Batch(actualSeries, predictedSeries, Period);
|
||||
Mase.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), Period);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -303,7 +303,7 @@ public class MaseTests
|
||||
}
|
||||
|
||||
// 1. Batch Mode (static method)
|
||||
var batchSeries = Mase.Calculate(actualSeries, predictedSeries, Period);
|
||||
var batchSeries = Mase.Batch(actualSeries, predictedSeries, Period);
|
||||
double expected = batchSeries.Last.Value;
|
||||
|
||||
// 2. Span Mode
|
||||
|
||||
+10
-3
@@ -162,7 +162,7 @@ public sealed class Mase : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("MASE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("MASE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -179,7 +179,7 @@ public sealed class Mase : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -352,4 +352,11 @@ public sealed class Mase : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mase Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mase(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ public class MdaeTests
|
||||
iterativeResults.Add(mdaeIterative.Update(actual, predicted).Value);
|
||||
}
|
||||
|
||||
var batchResults = Mdae.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = Mdae.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(100, iterativeResults.Count);
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
@@ -237,7 +237,7 @@ public class MdaeTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = Mdae.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = Mdae.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
Mdae.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -286,7 +286,7 @@ public class MdaeTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mdae.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => Mdae.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+10
-3
@@ -114,7 +114,7 @@ public sealed class Mdae : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("MdAE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("MdAE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -161,7 +161,7 @@ public sealed class Mdae : AbstractBase
|
||||
return (_sortBuffer[mid - 1] + _sortBuffer[mid]) * 0.5;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -299,6 +299,13 @@ public sealed class Mdae : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mdae Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mdae(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// QuickSelect for Span - finds the k-th smallest element in O(n) average time.
|
||||
/// Uses insertion sort for small arrays and Lomuto partition for larger arrays.
|
||||
@@ -378,4 +385,4 @@ public sealed class Mdae : AbstractBase
|
||||
|
||||
return span[left];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class MdapeTests
|
||||
iterativeResults.Add(mdapeIterative.Update(actualSeries[i], predictedSeries[i]));
|
||||
}
|
||||
|
||||
var batchResults = Mdape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = Mdape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < batchResults.Count; i++)
|
||||
@@ -238,7 +238,7 @@ public class MdapeTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = Mdape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = Mdape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
Mdape.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < tseriesResult.Count; i++)
|
||||
@@ -287,7 +287,7 @@ public class MdapeTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mdape.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => Mdape.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -68,7 +68,7 @@ public sealed class Mdape : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("MdAPE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("MdAPE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -164,7 +164,7 @@ public sealed class Mdape : AbstractBase
|
||||
return (_sortBuffer[mid - 1] + _sortBuffer[mid]) * 0.5;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -263,6 +263,13 @@ public sealed class Mdape : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mdape Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mdape(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dual-heap based sliding window median calculator.
|
||||
/// Maintains O(log n) insert/remove and O(1) median query.
|
||||
@@ -405,4 +412,4 @@ public sealed class Mdape : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public class MeTests
|
||||
predicted.Add(now.AddMinutes(i), i * 10 + 5);
|
||||
}
|
||||
|
||||
var results = Me.Calculate(actual, predicted, 3);
|
||||
var results = Me.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// All errors are -5, so ME should be -5
|
||||
@@ -357,7 +357,7 @@ public class MeTests
|
||||
predicted.Add(DateTime.UtcNow, i);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Me.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Me.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+9
-2
@@ -40,7 +40,7 @@ public sealed class Me : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates ME for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -78,4 +78,11 @@ public sealed class Me : BiInputIndicatorBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Me Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Me(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -236,7 +236,7 @@ public class MpeTests
|
||||
iterativeResults.Add(mpeIterative.Update(actualSeries[i], predictedSeries[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Mpe.Calculate(actualSeries, predictedSeries, 10);
|
||||
var batchResults = Mpe.Batch(actualSeries, predictedSeries, 10);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -280,7 +280,7 @@ public class MpeTests
|
||||
predictedSeries.Add(bar.Time, bar.Close * 0.95);
|
||||
}
|
||||
|
||||
var tseriesResult = Mpe.Calculate(actualSeries, predictedSeries, 10);
|
||||
var tseriesResult = Mpe.Batch(actualSeries, predictedSeries, 10);
|
||||
Mpe.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), 10);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -314,7 +314,7 @@ public class MpeTests
|
||||
actual.Add(DateTime.UtcNow.Ticks + 1, 100);
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 90);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mpe.Calculate(actual, predicted, 5));
|
||||
Assert.Throws<ArgumentException>(() => Mpe.Batch(actual, predicted, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -52,7 +52,7 @@ public sealed class Mpe : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates MPE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -78,6 +78,13 @@ public sealed class Mpe : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mpe Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mpe(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void ComputeSignedPercentageErrors(ReadOnlySpan<double> actual, ReadOnlySpan<double> predicted, Span<double> output)
|
||||
{
|
||||
@@ -139,4 +146,4 @@ public sealed class Mpe : BiInputIndicatorBase
|
||||
output[i] = 100.0 * (act - pred) / divisor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,7 +284,7 @@ public class MraeTests
|
||||
predicted.Add(now.AddMinutes(i), i * 110); // 10% error
|
||||
}
|
||||
|
||||
var results = Mrae.Calculate(actual, predicted, 3);
|
||||
var results = Mrae.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
Assert.Equal(0.1, results.Last.Value, 10);
|
||||
@@ -306,7 +306,7 @@ public class MraeTests
|
||||
predicted.Add(DateTime.UtcNow, i * 10);
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Mrae.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Mrae.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed class Mrae : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates Mean Relative Absolute Error for two time series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -104,6 +104,13 @@ public sealed class Mrae : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mrae Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mrae(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes relative errors (0-1 scale, not percentage).
|
||||
/// </summary>
|
||||
@@ -163,4 +170,4 @@ public sealed class Mrae : BiInputIndicatorBase
|
||||
: 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ public class MseTests
|
||||
predicted.Add(now.AddMinutes(i), i * 10 + 5);
|
||||
}
|
||||
|
||||
var results = Mse.Calculate(actual, predicted, 3);
|
||||
var results = Mse.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// All errors are 5², so MSE should be 25
|
||||
|
||||
@@ -46,7 +46,7 @@ public sealed class Mse : BiInputIndicatorBase
|
||||
/// <param name="predicted">Predicted values series</param>
|
||||
/// <param name="period">MSE period</param>
|
||||
/// <returns>MSE series</returns>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -78,4 +78,11 @@ public sealed class Mse : BiInputIndicatorBase
|
||||
// Apply rolling mean using shared helper
|
||||
ErrorHelpers.ApplyRollingMean(sqErrors, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Mse Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Mse(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public class MsleTests
|
||||
iterativeResults.Add(msleIterative.Update(actualSeries[i], predictedSeries[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Msle.Calculate(actualSeries, predictedSeries, 10);
|
||||
var batchResults = Msle.Batch(actualSeries, predictedSeries, 10);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -285,7 +285,7 @@ public class MsleTests
|
||||
predictedSeries.Add(bar.Time, bar.Close * 0.95);
|
||||
}
|
||||
|
||||
var tseriesResult = Msle.Calculate(actualSeries, predictedSeries, 10);
|
||||
var tseriesResult = Msle.Batch(actualSeries, predictedSeries, 10);
|
||||
Msle.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), 10);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -319,7 +319,7 @@ public class MsleTests
|
||||
actual.Add(DateTime.UtcNow.Ticks + 1, 100);
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 90);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Msle.Calculate(actual, predicted, 5));
|
||||
Assert.Throws<ArgumentException>(() => Msle.Batch(actual, predicted, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -46,7 +46,7 @@ public sealed class Msle : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates MSLE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -72,6 +72,13 @@ public sealed class Msle : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Msle Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Msle(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void ComputeLogSquaredErrors(ReadOnlySpan<double> actual, ReadOnlySpan<double> predicted, Span<double> output)
|
||||
{
|
||||
@@ -127,4 +134,4 @@ public sealed class Msle : BiInputIndicatorBase
|
||||
output[i] = logError * logError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ public class PseudoHuberTests
|
||||
}
|
||||
|
||||
// Calculate batch
|
||||
var batchResults = PseudoHuber.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = PseudoHuber.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
// Compare
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
@@ -389,7 +389,7 @@ public class PseudoHuberTests
|
||||
predictedSeries.Add(bar.Time, predictedData[i]);
|
||||
}
|
||||
|
||||
var tseriesResult = PseudoHuber.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = PseudoHuber.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
PseudoHuber.Batch(actualData.AsSpan(), predictedData.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -445,7 +445,7 @@ public class PseudoHuberTests
|
||||
actual.Add(DateTime.UtcNow, 101);
|
||||
predicted.Add(DateTime.UtcNow, 99);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => PseudoHuber.Calculate(actual, predicted, 5));
|
||||
Assert.Throws<ArgumentException>(() => PseudoHuber.Batch(actual, predicted, 5));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class PseudoHuber : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates Pseudo-Huber Loss for two time series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period, double delta = 1.0)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period, double delta = 1.0)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -124,4 +124,11 @@ public sealed class PseudoHuber : BiInputIndicatorBase
|
||||
// Apply rolling mean
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, PseudoHuber Indicator) Calculate(TSeries actual, TSeries predicted, int period, double delta = 1.0)
|
||||
{
|
||||
var indicator = new PseudoHuber(period, delta);
|
||||
TSeries results = Batch(actual, predicted, period, delta);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -237,7 +237,7 @@ public class QuantileLossTests
|
||||
|
||||
var iterativeResults = actualSeries.Zip(predictedSeries, (actual, predicted) => quantileLossIterative.Update(actual.Value, predicted.Value).Value).ToList();
|
||||
|
||||
var batchResults = QuantileLoss.Calculate(actualSeries, predictedSeries, DefaultPeriod, 0.75);
|
||||
var batchResults = QuantileLoss.Batch(actualSeries, predictedSeries, DefaultPeriod, 0.75);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
int count = iterativeResults.Count;
|
||||
@@ -288,7 +288,7 @@ public class QuantileLossTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = QuantileLoss.Calculate(actualSeries, predictedSeries, DefaultPeriod, 0.75);
|
||||
var tseriesResult = QuantileLoss.Batch(actualSeries, predictedSeries, DefaultPeriod, 0.75);
|
||||
QuantileLoss.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod, 0.75);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -337,7 +337,7 @@ public class QuantileLossTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => QuantileLoss.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => QuantileLoss.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -60,7 +60,7 @@ public sealed class QuantileLoss : BiInputIndicatorBase
|
||||
return diff >= 0 ? Quantile * diff : (Quantile - 1.0) * diff;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period, double quantile = 0.5)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period, double quantile = 0.5)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -220,4 +220,11 @@ public sealed class QuantileLoss : BiInputIndicatorBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, QuantileLoss Indicator) Calculate(TSeries actual, TSeries predicted, int period, double quantile = 0.5)
|
||||
{
|
||||
var indicator = new QuantileLoss(period, quantile);
|
||||
TSeries results = Batch(actual, predicted, period, quantile);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ public class RaeTests
|
||||
iterativeResults.Add(raeIterative.Update(actual[i], predicted[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Rae.Calculate(actual, predicted, Period);
|
||||
var batchResults = Rae.Batch(actual, predicted, Period);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -271,7 +271,7 @@ public class RaeTests
|
||||
double[] predictedArr = predictedSeries.Values.ToArray();
|
||||
double[] output = new double[100];
|
||||
|
||||
var tseriesResult = Rae.Calculate(actualSeries, predictedSeries, Period);
|
||||
var tseriesResult = Rae.Batch(actualSeries, predictedSeries, Period);
|
||||
Rae.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), Period);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -292,7 +292,7 @@ public class RaeTests
|
||||
}
|
||||
|
||||
// 1. Batch Mode (static method)
|
||||
var batchSeries = Rae.Calculate(actualSeries, predictedSeries, Period);
|
||||
var batchSeries = Rae.Batch(actualSeries, predictedSeries, Period);
|
||||
double expected = batchSeries.Last.Value;
|
||||
|
||||
// 2. Span Mode
|
||||
|
||||
@@ -159,7 +159,7 @@ public sealed class Rae : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("RAE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("RAE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -177,7 +177,7 @@ public sealed class Rae : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -355,4 +355,11 @@ public sealed class Rae : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Rae Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Rae(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public class RmseTests
|
||||
predicted.Add(now.AddMinutes(i), i * 10 + 5);
|
||||
}
|
||||
|
||||
var results = Rmse.Calculate(actual, predicted, 3);
|
||||
var results = Rmse.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// All errors are 5, MSE = 25, RMSE = 5
|
||||
|
||||
@@ -45,7 +45,7 @@ public sealed class Rmse : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates RMSE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -70,4 +70,11 @@ public sealed class Rmse : BiInputIndicatorBase
|
||||
ErrorHelpers.ComputeSquaredErrors(actual, predicted, sqErrors);
|
||||
ErrorHelpers.ApplyRollingMeanSqrt(sqErrors, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Rmse Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Rmse(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -222,7 +222,7 @@ public class RmsleTests
|
||||
iterativeResults.Add(rmsleIterative.Update(actualSeries[i], predictedSeries[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Rmsle.Calculate(actualSeries, predictedSeries, 10);
|
||||
var batchResults = Rmsle.Batch(actualSeries, predictedSeries, 10);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -266,7 +266,7 @@ public class RmsleTests
|
||||
predictedSeries.Add(bar.Time, bar.Close * 0.95);
|
||||
}
|
||||
|
||||
var tseriesResult = Rmsle.Calculate(actualSeries, predictedSeries, 10);
|
||||
var tseriesResult = Rmsle.Batch(actualSeries, predictedSeries, 10);
|
||||
Rmsle.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), 10);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -300,7 +300,7 @@ public class RmsleTests
|
||||
actual.Add(DateTime.UtcNow.Ticks + 1, 100);
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 90);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Rmsle.Calculate(actual, predicted, 5));
|
||||
Assert.Throws<ArgumentException>(() => Rmsle.Batch(actual, predicted, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed class Rmsle : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates RMSLE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -75,6 +75,13 @@ public sealed class Rmsle : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMeanSqrt(errors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Rmsle Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Rmsle(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void ComputeLogSquaredErrors(ReadOnlySpan<double> actual, ReadOnlySpan<double> predicted, Span<double> output)
|
||||
{
|
||||
@@ -130,4 +137,4 @@ public sealed class Rmsle : BiInputIndicatorBase
|
||||
output[i] = logError * logError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@ public class RseTests
|
||||
iterativeResults.Add(rseIterative.Update(actual[i], predicted[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Rse.Calculate(actual, predicted, Period);
|
||||
var batchResults = Rse.Batch(actual, predicted, Period);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -294,7 +294,7 @@ public class RseTests
|
||||
double[] predictedArr = predictedSeries.Values.ToArray();
|
||||
double[] output = new double[100];
|
||||
|
||||
var tseriesResult = Rse.Calculate(actualSeries, predictedSeries, Period);
|
||||
var tseriesResult = Rse.Batch(actualSeries, predictedSeries, Period);
|
||||
Rse.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), Period);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -315,7 +315,7 @@ public class RseTests
|
||||
}
|
||||
|
||||
// 1. Batch Mode (static method)
|
||||
var batchSeries = Rse.Calculate(actualSeries, predictedSeries, Period);
|
||||
var batchSeries = Rse.Batch(actualSeries, predictedSeries, Period);
|
||||
double expected = batchSeries.Last.Value;
|
||||
|
||||
// 2. Span Mode
|
||||
|
||||
+10
-3
@@ -166,7 +166,7 @@ public sealed class Rse : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("RSE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("RSE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -184,7 +184,7 @@ public sealed class Rse : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -366,4 +366,11 @@ public sealed class Rse : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Rse Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Rse(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -290,7 +290,7 @@ public class RsquaredTests
|
||||
iterativeResults.Add(r2Iterative.Update(actual[i], predicted[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Rsquared.Calculate(actual, predicted, Period);
|
||||
var batchResults = Rsquared.Batch(actual, predicted, Period);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -331,7 +331,7 @@ public class RsquaredTests
|
||||
double[] predictedArr = predictedSeries.Values.ToArray();
|
||||
double[] output = new double[100];
|
||||
|
||||
var tseriesResult = Rsquared.Calculate(actualSeries, predictedSeries, Period);
|
||||
var tseriesResult = Rsquared.Batch(actualSeries, predictedSeries, Period);
|
||||
Rsquared.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), Period);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -352,7 +352,7 @@ public class RsquaredTests
|
||||
}
|
||||
|
||||
// 1. Batch Mode (static method)
|
||||
var batchSeries = Rsquared.Calculate(actualSeries, predictedSeries, Period);
|
||||
var batchSeries = Rsquared.Batch(actualSeries, predictedSeries, Period);
|
||||
double expected = batchSeries.Last.Value;
|
||||
|
||||
// 2. Span Mode
|
||||
|
||||
@@ -160,7 +160,7 @@ public sealed class Rsquared : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("R² requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("R² requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -178,7 +178,7 @@ public sealed class Rsquared : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -360,4 +360,11 @@ public sealed class Rsquared : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Rsquared Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Rsquared(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -217,7 +217,7 @@ public class SmapeTests
|
||||
iterativeResults.Add(smapeIterative.Update(actualSeries[i], predictedSeries[i]).Value);
|
||||
}
|
||||
|
||||
var batchResults = Smape.Calculate(actualSeries, predictedSeries, 10);
|
||||
var batchResults = Smape.Batch(actualSeries, predictedSeries, 10);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -261,7 +261,7 @@ public class SmapeTests
|
||||
predictedSeries.Add(bar.Time, bar.Close * 0.95);
|
||||
}
|
||||
|
||||
var tseriesResult = Smape.Calculate(actualSeries, predictedSeries, 10);
|
||||
var tseriesResult = Smape.Batch(actualSeries, predictedSeries, 10);
|
||||
Smape.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), 10);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -295,7 +295,7 @@ public class SmapeTests
|
||||
actual.Add(DateTime.UtcNow.Ticks + 1, 100);
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 90);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Smape.Calculate(actual, predicted, 5));
|
||||
Assert.Throws<ArgumentException>(() => Smape.Batch(actual, predicted, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class Smape : BiInputIndicatorBase
|
||||
/// <summary>
|
||||
/// Calculates SMAPE for entire series.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
=> CalculateImpl(actual, predicted, period, Batch);
|
||||
|
||||
/// <summary>
|
||||
@@ -70,6 +70,13 @@ public sealed class Smape : BiInputIndicatorBase
|
||||
ErrorHelpers.ApplyRollingMean(symErrors, output, period);
|
||||
}
|
||||
|
||||
public static (TSeries Results, Smape Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Smape(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void ComputeSmapeErrors(ReadOnlySpan<double> actual, ReadOnlySpan<double> predicted, Span<double> output)
|
||||
{
|
||||
@@ -122,4 +129,4 @@ public sealed class Smape : BiInputIndicatorBase
|
||||
output[i] = sumAbs > Epsilon ? 200.0 * absDiff / sumAbs : 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ public class TheilUTests
|
||||
iterativeResults.Add(theilUIterative.Update(new TValue(bar.Time, bar.Close), new TValue(bar.Time, predicted)).Value);
|
||||
}
|
||||
|
||||
var batchResults = TheilU.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = TheilU.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -236,7 +236,7 @@ public class TheilUTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = TheilU.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = TheilU.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
TheilU.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -285,7 +285,7 @@ public class TheilUTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => TheilU.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => TheilU.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -75,7 +75,7 @@ public sealed class TheilU : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("TheilU requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("TheilU requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -170,7 +170,7 @@ public sealed class TheilU : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -352,4 +352,11 @@ public sealed class TheilU : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, TheilU Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new TheilU(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public class TukeyBiweightTests
|
||||
iterativeResults.Add(tukeyIterative.Update(actual, predicted).Value);
|
||||
}
|
||||
|
||||
var batchResults = TukeyBiweight.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = TukeyBiweight.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
Assert.Equal(iterativeResults.Count, batchResults.Count);
|
||||
for (int i = 0; i < iterativeResults.Count; i++)
|
||||
@@ -282,7 +282,7 @@ public class TukeyBiweightTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = TukeyBiweight.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = TukeyBiweight.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
TukeyBiweight.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -331,7 +331,7 @@ public class TukeyBiweightTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => TukeyBiweight.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => TukeyBiweight.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -66,7 +66,7 @@ public sealed class TukeyBiweight : BiInputIndicatorBase
|
||||
return _cSquaredOver6 * (1.0 - cubed);
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period, double c = DefaultC)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period, double c = DefaultC)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -129,4 +129,11 @@ public sealed class TukeyBiweight : BiInputIndicatorBase
|
||||
ArrayPool<double>.Shared.Return(rented, clearArray: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, TukeyBiweight Indicator) Calculate(TSeries actual, TSeries predicted, int period, double c = DefaultC)
|
||||
{
|
||||
var indicator = new TukeyBiweight(period, c);
|
||||
TSeries results = Batch(actual, predicted, period, c);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ public class WmapeTests
|
||||
predictedSeries.Add(bar.Time, bar.Close * (1 + (i % 2 == 0 ? 0.02 : -0.02)));
|
||||
}
|
||||
|
||||
var batchResults = Wmape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var batchResults = Wmape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
|
||||
var iterativeResults = new List<double>();
|
||||
for (int i = 0; i < actualSeries.Count; i++)
|
||||
@@ -236,7 +236,7 @@ public class WmapeTests
|
||||
predictedArr[i] = pred;
|
||||
}
|
||||
|
||||
var tseriesResult = Wmape.Calculate(actualSeries, predictedSeries, DefaultPeriod);
|
||||
var tseriesResult = Wmape.Batch(actualSeries, predictedSeries, DefaultPeriod);
|
||||
Wmape.Batch(actualArr.AsSpan(), predictedArr.AsSpan(), output.AsSpan(), DefaultPeriod);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -285,7 +285,7 @@ public class WmapeTests
|
||||
|
||||
predicted.Add(DateTime.UtcNow.Ticks, 98);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Wmape.Calculate(actual, predicted, DefaultPeriod));
|
||||
Assert.Throws<ArgumentException>(() => Wmape.Batch(actual, predicted, DefaultPeriod));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -138,7 +138,7 @@ public sealed class Wmape : AbstractBase
|
||||
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("WMAPE requires two inputs. Use Calculate(actualSeries, predictedSeries, period).");
|
||||
throw new NotSupportedException("WMAPE requires two inputs. Use Batch(actualSeries, predictedSeries, period).");
|
||||
}
|
||||
|
||||
public override void Prime(ReadOnlySpan<double> source, TimeSpan? step = null)
|
||||
@@ -155,7 +155,7 @@ public sealed class Wmape : AbstractBase
|
||||
Last = default;
|
||||
}
|
||||
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -345,4 +345,11 @@ public sealed class Wmape : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Wmape Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Wmape(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
@@ -320,7 +320,7 @@ public class WrmseTests
|
||||
predicted.Add(now.AddMinutes(i), i * 10 + 5);
|
||||
}
|
||||
|
||||
var results = Wrmse.Calculate(actual, predicted, 3);
|
||||
var results = Wrmse.Batch(actual, predicted, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// All errors are 5, MSE = 25, RMSE = 5
|
||||
@@ -342,7 +342,7 @@ public class WrmseTests
|
||||
weights.Add(now.AddMinutes(i), 2.0); // Weight = 2
|
||||
}
|
||||
|
||||
var results = Wrmse.Calculate(actual, predicted, weights, 3);
|
||||
var results = Wrmse.Batch(actual, predicted, weights, 3);
|
||||
|
||||
Assert.Equal(10, results.Count);
|
||||
// Weighted error = 2 * 100 = 200 per point, sum weights = 6 (period=3)
|
||||
@@ -366,7 +366,7 @@ public class WrmseTests
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Wrmse.Calculate(actual, predicted, 3));
|
||||
Assert.Throws<ArgumentException>(() => Wrmse.Batch(actual, predicted, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -387,7 +387,7 @@ public class WrmseTests
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(() => Wrmse.Calculate(actual, predicted, weights, 3));
|
||||
Assert.Throws<ArgumentException>(() => Wrmse.Batch(actual, predicted, weights, 3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -197,7 +197,7 @@ public sealed class Wrmse : AbstractBase
|
||||
/// <inheritdoc/>
|
||||
public override TSeries Update(TSeries source)
|
||||
{
|
||||
throw new NotSupportedException("WRMSE requires two inputs. Use Calculate(actualSeries, predictedSeries, period) or Calculate(actualSeries, predictedSeries, weightsSeries, period).");
|
||||
throw new NotSupportedException("WRMSE requires two inputs. Use Batch(actualSeries, predictedSeries, period) or Batch(actualSeries, predictedSeries, weightsSeries, period).");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -221,7 +221,7 @@ public sealed class Wrmse : AbstractBase
|
||||
/// <summary>
|
||||
/// Calculates WRMSE for entire series with uniform weights.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count)
|
||||
{
|
||||
@@ -246,7 +246,7 @@ public sealed class Wrmse : AbstractBase
|
||||
/// <summary>
|
||||
/// Calculates WRMSE for entire series with custom weights.
|
||||
/// </summary>
|
||||
public static TSeries Calculate(TSeries actual, TSeries predicted, TSeries weights, int period)
|
||||
public static TSeries Batch(TSeries actual, TSeries predicted, TSeries weights, int period)
|
||||
{
|
||||
if (actual.Count != predicted.Count || actual.Count != weights.Count)
|
||||
{
|
||||
@@ -332,4 +332,11 @@ public sealed class Wrmse : AbstractBase
|
||||
ErrorHelpers.ComputeWeightedErrors(actual, predicted, weights, weightedErrors);
|
||||
ErrorHelpers.ApplyRollingWeightedMeanSqrt(weightedErrors, weights, output, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static (TSeries Results, Wrmse Indicator) Calculate(TSeries actual, TSeries predicted, int period)
|
||||
{
|
||||
var indicator = new Wrmse(period);
|
||||
TSeries results = Batch(actual, predicted, period);
|
||||
return (results, indicator);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user