LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
TemporalPatternAnalyzer.cs
Go to the documentation of this file.
2
3/// <summary>
4/// Classifies a numerical time series as Zero, Constant, NonIncreasing,
5/// NonDecreasing or General.
6/// </summary>
7/// <remarks>
8/// Canonical specificity is deterministic:
9/// Zero > Constant > directional monotonicity > General.
10///
11/// Numerical comparisons use one effective tolerance computed from the
12/// maximum absolute value in the complete series. When tolerance makes a
13/// non-constant series simultaneously non-increasing and non-decreasing,
14/// the analyzer conservatively returns General instead of choosing an
15/// arbitrary direction.
16/// </remarks>
17public sealed class TemporalPatternAnalyzer
18{
20 IEnumerable<double> values,
21 TemporalPatternTolerance? tolerance = null)
22 {
23 ArgumentNullException.ThrowIfNull(values);
24
25 double[] series = values.ToArray();
26
27 if (series.Length == 0)
28 {
29 throw new ArgumentException(
30 "Temporal-pattern analysis requires at least one value.",
31 nameof(values));
32 }
33
34 for (int index = 0; index < series.Length; index++)
35 {
36 if (!double.IsFinite(series[index]))
37 {
38 throw new ArgumentOutOfRangeException(
39 nameof(values),
40 series[index],
41 $"Value at zero-based index {index} is not finite.");
42 }
43 }
44
47
48 double maximumAbsoluteValue =
49 series.Max(value => Math.Abs(value));
50
51 double epsilon =
53 maximumAbsoluteValue);
54
55 double minimum = series.Min();
56 double maximum = series.Max();
57
58 bool isZero =
59 maximumAbsoluteValue <= epsilon;
60
61 bool isConstant =
62 maximum - minimum <= epsilon;
63
64 bool isNonIncreasing = true;
65 bool isNonDecreasing = true;
66
67 for (int index = 1; index < series.Length; index++)
68 {
69 double previous = series[index - 1];
70 double current = series[index];
71
72 if (current > previous + epsilon)
73 {
74 isNonIncreasing = false;
75 }
76
77 if (current < previous - epsilon)
78 {
79 isNonDecreasing = false;
80 }
81 }
82
83 TemporalPatternType pattern;
84
85 if (isZero)
86 {
87 pattern = TemporalPatternType.Zero;
88 }
89 else if (isConstant)
90 {
91 pattern = TemporalPatternType.Constant;
92 }
93 else if (isNonIncreasing && !isNonDecreasing)
94 {
95 pattern = TemporalPatternType.NonIncreasing;
96 }
97 else if (isNonDecreasing && !isNonIncreasing)
98 {
99 pattern = TemporalPatternType.NonDecreasing;
100 }
101 else
102 {
103 pattern = TemporalPatternType.General;
104 }
105
106 return new TemporalPatternAnalysis(
107 pattern,
108 series.Length,
109 series[0],
110 series[^1],
111 minimum,
112 maximum,
113 epsilon);
114 }
115}
Represents the deterministic analysis of one finite, non-empty time series.
Classifies a numerical time series as Zero, Constant, NonIncreasing, NonDecreasing or General.
TemporalPatternAnalysis Analyze(IEnumerable< double > values, TemporalPatternTolerance? tolerance=null)
Defines the numerical tolerance policy used for temporal-pattern analysis.
double GetEffectiveTolerance(double scale)
Computes the effective absolute tolerance for a given value scale.
static TemporalPatternTolerance Default
Gets the default conservative numerical tolerance.
TemporalPatternType
Canonical temporal-pattern categories used by historical lot-sizing classifications such as Bitran-Ya...