Browse Source

Precision: migrate epsilon logic from NumericalDerivative to Precision class

pull/282/head
Christoph Ruegg 12 years ago
parent
commit
c72bb3662e
  1. 17
      src/Numerics/Differentiation/NumericalDerivative.cs
  2. 66
      src/Numerics/Precision.cs
  3. 2
      src/Numerics/RootFinding/Brent.cs

17
src/Numerics/Differentiation/NumericalDerivative.cs

@ -174,7 +174,7 @@ namespace MathNet.Numerics.Differentiation
throw new ArgumentOutOfRangeException("points", "Points must be two or greater."); throw new ArgumentOutOfRangeException("points", "Points must be two or greater.");
_points = points; _points = points;
Center = center; Center = center;
_epsilon = CalculateMachineEpsilon(); _epsilon = Precision.PositiveMachineEpsilon;
_coefficients = new FiniteDifferenceCoefficients(points); _coefficients = new FiniteDifferenceCoefficients(points);
} }
@ -437,21 +437,6 @@ namespace MathNet.Numerics.Differentiation
Evaluations = 0; Evaluations = 0;
} }
/// <summary>
/// Calculates machine epsilon - the smallest number that can be added to 1, yeilding a results different than 1.
/// This is also known as roundoff error.
/// </summary>
/// <returns>Machine epislon</returns>
public static double CalculateMachineEpsilon()
{
double eps = 1;
while ((1.0d + (eps / 2.0d)) > 1.0d)
eps /= 2.0d;
return eps;
}
private double[] CalculateStepSize(int points, double[] x, double order) private double[] CalculateStepSize(int points, double[] x, double order)
{ {
var h = new double[x.Length]; var h = new double[x.Length];

66
src/Numerics/Precision.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2015 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -91,15 +91,43 @@ namespace MathNet.Numerics
const int SingleWidth = 24; const int SingleWidth = 24;
/// <summary> /// <summary>
/// The maximum relative precision of of double-precision floating numbers (64 bit) /// Standard epsilon, the maximum relative precision of IEEE 754 double-precision floating numbers (64 bit).
/// According to the definition of Prof. Demmel and used in LAPACK and Scilab.
/// </summary> /// </summary>
public static readonly double DoublePrecision = Math.Pow(2, -DoubleWidth); public static readonly double DoublePrecision = Math.Pow(2, -DoubleWidth);
/// <summary> /// <summary>
/// The maximum relative precision of of single-precision floating numbers (32 bit) /// Standard epsilon, the maximum relative precision of IEEE 754 double-precision floating numbers (64 bit).
/// According to the definition of Prof. Higham and used in the ISO C standard and MATLAB.
/// </summary>
public static readonly double PositiveDoublePrecision = 2*DoublePrecision;
/// <summary>
/// Standard epsilon, the maximum relative precision of IEEE 754 single-precision floating numbers (32 bit).
/// According to the definition of Prof. Demmel and used in LAPACK and Scilab.
/// </summary> /// </summary>
public static readonly double SinglePrecision = Math.Pow(2, -SingleWidth); public static readonly double SinglePrecision = Math.Pow(2, -SingleWidth);
/// <summary>
/// Standard epsilon, the maximum relative precision of IEEE 754 single-precision floating numbers (32 bit).
/// According to the definition of Prof. Higham and used in the ISO C standard and MATLAB.
/// </summary>
public static readonly double PositiveSinglePrecision = 2*SinglePrecision;
/// <summary>
/// Actual machine epsilon, the smallest number that can be subtracted from 1, yielding a results different than 1.
/// This is also known as unit roundoff error. According to the definition of Prof. Demmel.
/// On a standard machine this is equivalent to `DoublePrecision`.
/// </summary>
public static readonly double MachineEpsilon = MeasureMachineEpsilon();
/// <summary>
/// Actual machine epsilon, the smallest number that can be added to 1, yielding a results different than 1.
/// This is also known as unit roundoff error. According to the definition of Prof. Higham.
/// On a standard machine this is equivalent to `PositiveDoublePrecision`.
/// </summary>
public static readonly double PositiveMachineEpsilon = MeasurePositiveMachineEpsilon();
/// <summary> /// <summary>
/// The number of significant decimal places of double-precision floating numbers (64 bit). /// The number of significant decimal places of double-precision floating numbers (64 bit).
/// </summary> /// </summary>
@ -761,7 +789,7 @@ namespace MathNet.Numerics
} }
/// <summary> /// <summary>
/// Converts a float valut to a bit array stored in an int. /// Converts a float value to a bit array stored in an int.
/// </summary> /// </summary>
/// <param name="value">The value to convert.</param> /// <param name="value">The value to convert.</param>
/// <returns>The bit array.</returns> /// <returns>The bit array.</returns>
@ -770,6 +798,36 @@ namespace MathNet.Numerics
return BitConverter.ToInt32(BitConverter.GetBytes(value), 0); return BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
} }
/// <summary>
/// Calculates the actual positive double precision machine epsilon - the smallest number that can be added to 1, yielding a results different than 1.
/// This is also known as unit roundoff error. According to the definition of Prof. Demmel.
/// </summary>
/// <returns>Positive Machine epsilon</returns>
static double MeasureMachineEpsilon()
{
double eps = 1.0d;
while ((1.0d - (eps / 2.0d)) < 1.0d)
eps /= 2.0d;
return eps;
}
/// <summary>
/// Calculates the actual positive double precision machine epsilon - the smallest number that can be added to 1, yielding a results different than 1.
/// This is also known as unit roundoff error. According to the definition of Prof. Higham.
/// </summary>
/// <returns>Machine epsilon</returns>
static double MeasurePositiveMachineEpsilon()
{
double eps = 1.0d;
while ((1.0d + (eps / 2.0d)) > 1.0d)
eps /= 2.0d;
return eps;
}
#if PORTABLE #if PORTABLE
static long DoubleToInt64Bits(double value) static long DoubleToInt64Bits(double value)
{ {

2
src/Numerics/RootFinding/Brent.cs

@ -119,7 +119,7 @@ namespace MathNet.Numerics.RootFinding
} }
// convergence check // convergence check
double xAcc1 = 2.0*Precision.DoublePrecision*Math.Abs(root) + 0.5*accuracy; double xAcc1 = Precision.PositiveDoublePrecision*Math.Abs(root) + 0.5*accuracy;
double xMidOld = xMid; double xMidOld = xMid;
xMid = (upperBound - root)/2.0; xMid = (upperBound - root)/2.0;

Loading…
Cancel
Save