Browse Source

Merge pull request #757 from febkor/optimize/minor

Minor performance
v4
Christoph Ruegg 6 years ago
committed by GitHub
parent
commit
8ba26ce45f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      src/Numerics/Distributions/Cauchy.cs
  2. 1
      src/Numerics/Interpolation/CubicSpline.cs
  3. 22
      src/Numerics/Precision.Equality.cs

13
src/Numerics/Distributions/Cauchy.cs

@ -179,7 +179,8 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDF"/> /// <seealso cref="PDF"/>
public double Density(double x) public double Density(double x)
{ {
return 1.0/(Constants.Pi*_scale*(1.0 + (((x - _location)/_scale)*((x - _location)/_scale)))); var z = (x - _location)/_scale;
return 1.0/(Constants.Pi*_scale*(1.0 + z * z));
} }
/// <summary> /// <summary>
@ -190,7 +191,8 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDFLn"/> /// <seealso cref="PDFLn"/>
public double DensityLn(double x) public double DensityLn(double x)
{ {
return -Math.Log(Constants.Pi*_scale*(1.0 + (((x - _location)/_scale)*((x - _location)/_scale)))); var z = (x - _location)/_scale;
return -Math.Log(Constants.Pi*_scale*(1.0 + z * z));
} }
/// <summary> /// <summary>
@ -283,9 +285,9 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException("Invalid parametrization for the distribution."); throw new ArgumentException("Invalid parametrization for the distribution.");
} }
return 1.0/(Constants.Pi*scale*(1.0 + (((x - location)/scale)*((x - location)/scale)))); var z = (x - location)/scale;
return 1.0/(Constants.Pi*scale*(1.0 + z * z));
} }
/// <summary> /// <summary>
/// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x).
/// </summary> /// </summary>
@ -301,7 +303,8 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException("Invalid parametrization for the distribution."); throw new ArgumentException("Invalid parametrization for the distribution.");
} }
return -Math.Log(Constants.Pi*scale*(1.0 + (((x - location)/scale)*((x - location)/scale)))); var z = (x - location)/scale;
return -Math.Log(Constants.Pi*scale*(1.0 + z * z ));
} }
/// <summary> /// <summary>

1
src/Numerics/Interpolation/CubicSpline.cs

@ -237,7 +237,6 @@ namespace MathNet.Numerics.Interpolation
var dd = new double[x.Length]; var dd = new double[x.Length];
var hPrev = x[1] - x[0]; var hPrev = x[1] - x[0];
// This check is quite costly as it usually involves a Math.Pow().
var mPrevIs0 = m[0].AlmostEqual(0.0); var mPrevIs0 = m[0].AlmostEqual(0.0);
for (var i = 1; i < x.Length - 1; ++i) for (var i = 1; i < x.Length - 1; ++i)

22
src/Numerics/Precision.Equality.cs

@ -34,8 +34,6 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics namespace MathNet.Numerics
{ {
// TODO PERF: Cache/Precompute 10^x terms
public static partial class Precision public static partial class Precision
{ {
/// <summary> /// <summary>
@ -355,7 +353,7 @@ namespace MathNet.Numerics
// 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range // 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range
// on each side of the numbers, e.g. if decimalPlaces == 2, // on each side of the numbers, e.g. if decimalPlaces == 2,
// then 0.01 will equal between 0.005 and 0.015, but not 0.02 and not 0.00 // then 0.01 will equal between 0.005 and 0.015, but not 0.02 and not 0.00
return Math.Abs(diff) < Math.Pow(10, -decimalPlaces) / 2d; return Math.Abs(diff) < Pow10(-decimalPlaces) * 0.5;
} }
/// <summary> /// <summary>
@ -431,7 +429,7 @@ namespace MathNet.Numerics
// 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range // 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range
// on each side of the numbers, e.g. if decimalPlaces == 2, // on each side of the numbers, e.g. if decimalPlaces == 2,
// then 0.01 will equal between 0.005 and 0.015, but not 0.02 and not 0.00 // then 0.01 will equal between 0.005 and 0.015, but not 0.02 and not 0.00
return Math.Abs(diff) < Math.Pow(10, -decimalPlaces) / 2d; return Math.Abs(diff) < Pow10(-decimalPlaces) * 0.5;
} }
// If the magnitudes of the two numbers are equal to within one magnitude the numbers could potentially be equal // If the magnitudes of the two numbers are equal to within one magnitude the numbers could potentially be equal
@ -447,7 +445,7 @@ namespace MathNet.Numerics
// 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range // 10^(-numberOfDecimalPlaces). We divide by two so that we have half the range
// on each side of the numbers, e.g. if decimalPlaces == 2, // on each side of the numbers, e.g. if decimalPlaces == 2,
// then 0.01 will equal between 0.00995 and 0.01005, but not 0.0015 and not 0.0095 // then 0.01 will equal between 0.00995 and 0.01005, but not 0.0015 and not 0.0095
return Math.Abs(diff) < Math.Pow(10, magnitudeOfMax - decimalPlaces) / 2d; return Math.Abs(diff) < Pow10(magnitudeOfMax - decimalPlaces) * 0.5;
} }
/// <summary> /// <summary>
@ -1041,5 +1039,19 @@ namespace MathNet.Numerics
{ {
return AlmostEqualNormRelative(a.L2Norm(), b.L2Norm(), (a - b).L2Norm(), decimalPlaces); return AlmostEqualNormRelative(a.L2Norm(), b.L2Norm(), (a - b).L2Norm(), decimalPlaces);
} }
private static readonly double[] NegativePowersOf10 = new double[]
{
1, 0.1, 0.01, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16,
1e-17, 1e-18, 1e-19, 1e-20
};
private static double Pow10(int y)
{
return -NegativePowersOf10.Length < y && y <= 0
? NegativePowersOf10[-y]
: Math.Pow(10.0, y);
}
} }
} }

Loading…
Cancel
Save