Skip to content

Commit 313d7ba

Browse files
committed
Harden distribution parameter validation
1 parent a8006fc commit 313d7ba

25 files changed

Lines changed: 812 additions & 248 deletions

‎Numerics/Distributions/Bivariate Copulas/AMHCopula.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ public override double ThetaMaximum
8282
/// <inheritdoc/>
8383
public override ArgumentOutOfRangeException? ValidateParameter(double parameter, bool throwException)
8484
{
85+
if (double.IsNaN(parameter) || double.IsInfinity(parameter))
86+
{
87+
var exception = new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter must be finite.");
88+
if (throwException) throw exception;
89+
return exception;
90+
}
8591
if (parameter < ThetaMinimum)
8692
{
8793
if (throwException) throw new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter θ (theta) must be greater than or equal to " + ThetaMinimum.ToString() + ".");

‎Numerics/Distributions/Bivariate Copulas/Base/ArchimedeanCopula.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public override void SetCopulaParameters(double[] parameters)
4949
/// <inheritdoc/>
5050
public override ArgumentOutOfRangeException? ValidateParameter(double parameter, bool throwException)
5151
{
52+
if (double.IsNaN(parameter) || double.IsInfinity(parameter))
53+
{
54+
var exception = new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter must be finite.");
55+
if (throwException) throw exception;
56+
return exception;
57+
}
5258
if (parameter < ThetaMinimum)
5359
{
5460
if (throwException) throw new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter θ (theta) must be greater than or equal to " + ThetaMinimum.ToString() + ".");

‎Numerics/Distributions/Bivariate Copulas/FrankCopula.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ public override double ThetaMaximum
8181
/// <inheritdoc/>
8282
public override ArgumentOutOfRangeException? ValidateParameter(double parameter, bool throwException)
8383
{
84+
if (double.IsNaN(parameter) || double.IsInfinity(parameter))
85+
{
86+
var exception = new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter must be finite.");
87+
if (throwException) throw exception;
88+
return exception;
89+
}
8490
if (parameter < ThetaMinimum)
8591
{
8692
if (throwException) throw new ArgumentOutOfRangeException(nameof(Theta), "The dependency parameter θ (theta) must be greater than or equal to " + ThetaMinimum.ToString() + ".");

‎Numerics/Distributions/Bivariate Copulas/NormalCopula.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ public override double ThetaMaximum
9797
/// <inheritdoc/>
9898
public override ArgumentOutOfRangeException? ValidateParameter(double parameter, bool throwException)
9999
{
100+
if (double.IsNaN(parameter) || double.IsInfinity(parameter))
101+
{
102+
var exception = new ArgumentOutOfRangeException(nameof(Theta), "The correlation parameter must be finite.");
103+
if (throwException) throw exception;
104+
return exception;
105+
}
100106
if (parameter < ThetaMinimum)
101107
{
102108
if (throwException) throw new ArgumentOutOfRangeException(nameof(Theta), "The correlation parameter ρ (rho) must be greater than " + ThetaMinimum.ToString() + ".");

‎Numerics/Distributions/Bivariate Copulas/StudentTCopula.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ public override double ThetaMaximum
189189
/// <param name="throwException">When true, throws on the first invalid parameter; when false, returns the exception instead.</param>
190190
public ArgumentOutOfRangeException? ValidateParameters(double rho, double degreesOfFreedom, bool throwException)
191191
{
192+
if (double.IsNaN(rho) || double.IsInfinity(rho))
193+
{
194+
var exception = new ArgumentOutOfRangeException(nameof(Theta), "The correlation parameter must be finite.");
195+
if (throwException) throw exception;
196+
return exception;
197+
}
192198
if (rho < ThetaMinimum)
193199
{
194200
if (throwException) throw new ArgumentOutOfRangeException(nameof(Theta), "The correlation parameter ρ (rho) must be greater than " + ThetaMinimum.ToString() + ".");

‎Numerics/Distributions/Multivariate/BivariateEmpirical.cs‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ public void SetParameters(IList<double> x1Values, IList<double> x2Values, double
171171
}
172172

173173
// Check if X1 and X2 are in ascending order
174+
for (int i = 0; i < x1Values.Count; i++)
175+
{
176+
if (double.IsNaN(x1Values[i]) || double.IsInfinity(x1Values[i]))
177+
{
178+
if (throwException) throw new ArgumentOutOfRangeException("Primary Values", "Primary values must be finite.");
179+
return new ArgumentOutOfRangeException("Primary Values", "Primary values must be finite.");
180+
}
181+
}
174182
for (int i = 1; i < x1Values.Count; i++)
175183
{
176184
if (x1Values[i] <= x1Values[i - 1])
@@ -180,6 +188,14 @@ public void SetParameters(IList<double> x1Values, IList<double> x2Values, double
180188
return new ArgumentOutOfRangeException("Primary Values", "Primary values must be in ascending order.");
181189
}
182190
}
191+
for (int i = 0; i < x2Values.Count; i++)
192+
{
193+
if (double.IsNaN(x2Values[i]) || double.IsInfinity(x2Values[i]))
194+
{
195+
if (throwException) throw new ArgumentOutOfRangeException("Secondary Values", "Secondary values must be finite.");
196+
return new ArgumentOutOfRangeException("Secondary Values", "Secondary values must be finite.");
197+
}
198+
}
183199
for (int i = 1; i < x2Values.Count; i++)
184200
{
185201
if (x2Values[i] <= x2Values[i - 1])
@@ -208,7 +224,7 @@ public void SetParameters(IList<double> x1Values, IList<double> x2Values, double
208224
{
209225
for (int j = 0; j < pValues.GetLength(1); j++) // Columns
210226
{
211-
if (pValues[i, j] < 0.0d || pValues[i, j] > 1.0d)
227+
if (double.IsNaN(pValues[i, j]) || double.IsInfinity(pValues[i, j]) || pValues[i, j] < 0.0d || pValues[i, j] > 1.0d)
212228
{
213229
if (throwException) throw new ArgumentOutOfRangeException(nameof(ProbabilityValues), "Probability values must be equal to or between 0 and 1.");
214230
return new ArgumentOutOfRangeException(nameof(ProbabilityValues), "Probability values must be equal to or between 0 and 1.");

‎Numerics/Distributions/Multivariate/MultivariateNormal.cs‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,15 @@ private void CreateCorrelationMatrix()
300300
{
301301
var ex = new ArgumentOutOfRangeException(nameof(covariance), "Covariance matrix must not be null.");
302302
if (throwException) throw ex; else return ex;
303-
}
303+
}
304+
for (int i = 0; i < mean.Length; i++)
305+
{
306+
if (double.IsNaN(mean[i]) || double.IsInfinity(mean[i]))
307+
{
308+
var ex = new ArgumentOutOfRangeException(nameof(mean), "Mean values must be finite.");
309+
if (throwException) throw ex; else return ex;
310+
}
311+
}
304312
var m = new Matrix(covariance);
305313
if (!m.IsSquare)
306314
{
@@ -312,6 +320,17 @@ private void CreateCorrelationMatrix()
312320
var ex = new ArgumentOutOfRangeException(nameof(Covariance), "Mean length must match covariance dimension.");
313321
if (throwException) throw ex; else return ex;
314322
}
323+
for (int i = 0; i < m.NumberOfRows; i++)
324+
{
325+
for (int j = 0; j < m.NumberOfColumns; j++)
326+
{
327+
if (double.IsNaN(m[i, j]) || double.IsInfinity(m[i, j]))
328+
{
329+
var ex = new ArgumentOutOfRangeException(nameof(covariance), "Covariance values must be finite.");
330+
if (throwException) throw ex; else return ex;
331+
}
332+
}
333+
}
315334

316335
var chol = new CholeskyDecomposition(m);
317336
if (!chol.IsPositiveDefinite)

‎Numerics/Distributions/Multivariate/MultivariateStudentT.cs‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public void SetParameters(double degreesOfFreedom, double[] location, double[,]
314314
/// </returns>
315315
public ArgumentOutOfRangeException? ValidateParameters(double degreesOfFreedom, double[] location, double[,] scaleMatrix, bool throwException)
316316
{
317-
if (degreesOfFreedom <= 0)
317+
if (double.IsNaN(degreesOfFreedom) || double.IsInfinity(degreesOfFreedom) || degreesOfFreedom <= 0)
318318
{
319319
var ex = new ArgumentOutOfRangeException(nameof(degreesOfFreedom), "Degrees of freedom must be greater than zero.");
320320
if (throwException) throw ex; else return ex;
@@ -329,6 +329,14 @@ public void SetParameters(double degreesOfFreedom, double[] location, double[,]
329329
var ex = new ArgumentOutOfRangeException(nameof(scaleMatrix), "Scale matrix must not be null.");
330330
if (throwException) throw ex; else return ex;
331331
}
332+
for (int i = 0; i < location.Length; i++)
333+
{
334+
if (double.IsNaN(location[i]) || double.IsInfinity(location[i]))
335+
{
336+
var ex = new ArgumentOutOfRangeException(nameof(location), "Location values must be finite.");
337+
if (throwException) throw ex; else return ex;
338+
}
339+
}
332340
var m = new Matrix(scaleMatrix);
333341
if (!m.IsSquare)
334342
{
@@ -340,6 +348,17 @@ public void SetParameters(double degreesOfFreedom, double[] location, double[,]
340348
var ex = new ArgumentOutOfRangeException(nameof(scaleMatrix), "Location vector length must match scale matrix dimension.");
341349
if (throwException) throw ex; else return ex;
342350
}
351+
for (int i = 0; i < m.NumberOfRows; i++)
352+
{
353+
for (int j = 0; j < m.NumberOfColumns; j++)
354+
{
355+
if (double.IsNaN(m[i, j]) || double.IsInfinity(m[i, j]))
356+
{
357+
var ex = new ArgumentOutOfRangeException(nameof(scaleMatrix), "Scale-matrix values must be finite.");
358+
if (throwException) throw ex; else return ex;
359+
}
360+
}
361+
}
343362
try
344363
{
345364
var chol = new CholeskyDecomposition(m);

‎Numerics/Distributions/Univariate/Binomial.cs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,9 @@ public override double[] MaximumOfParameters
206206
/// <inheritdoc/>
207207
public override void SetParameters(IList<double> parameters)
208208
{
209-
ProbabilityOfSuccess = parameters[0];
210-
NumberOfTrials = (int)parameters[1];
209+
_probabilityOfSuccess = parameters[0];
210+
_numberOfTrials = (int)parameters[1];
211+
_parametersValid = ValidateParameters(parameters, false) is null;
211212
}
212213

213214
/// <inheritdoc/>

‎Numerics/Distributions/Univariate/ChiSquared.cs‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ public override double[] MaximumOfParameters
189189
/// <param name="v">The degrees of freedom ν (nu). Range: ν > 0.</param>
190190
public void SetParameters(double v)
191191
{
192-
DegreesOfFreedom = (int)v;
192+
_degreesOfFreedom = (int)v;
193+
_parametersValid = !double.IsNaN(v) && !double.IsInfinity(v) && ValidateParameters(_degreesOfFreedom, false) is null;
193194
}
194195

195196
/// <inheritdoc/>
@@ -218,6 +219,12 @@ public override void SetParameters(IList<double> parameters)
218219
/// <inheritdoc/>
219220
public override ArgumentOutOfRangeException? ValidateParameters(IList<double> parameters, bool throwException)
220221
{
222+
if (double.IsNaN(parameters[0]) || double.IsInfinity(parameters[0]))
223+
{
224+
var exception = new ArgumentOutOfRangeException(nameof(DegreesOfFreedom), "The degrees of freedom must be finite.");
225+
if (throwException) throw exception;
226+
return exception;
227+
}
221228
return ValidateParameters((int)parameters[0], throwException);
222229
}
223230

0 commit comments

Comments
 (0)