Skip to content

Commit

Permalink
CsCheck 3.0.0-rc2
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyLloyd committed Nov 1, 2023
1 parent dcffa32 commit 74e0750
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 276 deletions.
42 changes: 1 addition & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Test
run: dotnet run --project Tests -c Release -f net6.0 -r win-x64 --no-self-contained -- -perf --info --nost --time 60 --wait 10 --skip
windows_core_86:
runs-on: windows-latest
runs-on: windows-latest
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
Expand All @@ -55,46 +55,6 @@ jobs:
path: MKL.NET.Native/bin/build/win-x86/Release/MKL.NET.Native.dll
- name: Test
run: dotnet run --project Tests -c Release -f net6.0 -r win-x86 -- -perf --info --nost --time 60 --wait 10 --skip
windows_framework_64:
runs-on: windows-latest
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
steps:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: Download Native
run: ./Scripts/Download-Devel win-x64
- name: Build Native
run: |
cmake --version
cmake -A x64 -S MKL.NET.Native -B MKL.NET.Native/bin/build/win-x64
cmake --build MKL.NET.Native/bin/build/win-x64 --config Release --verbose
- name: Test
run: dotnet run --project Tests -c Release -f net48 -r win-x64 -- -perf --info --nost --time 60 --wait 10 --skip
windows_framework_86:
runs-on: windows-latest
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
steps:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: Download Native
run: ./Scripts/Download-Devel win-x86
- name: Build Native
run: |
cmake --version
cmake -A Win32 -S MKL.NET.Native -B MKL.NET.Native/bin/build/win-x86
cmake --build MKL.NET.Native/bin/build/win-x86 --config Release --verbose
- name: Test
run: dotnet run --project Tests -c Release -f net48 -r win-x86 -- -perf --info --nost --time 60 --wait 10 --skip
linux_core_64:
runs-on: ubuntu-latest
env:
Expand Down
18 changes: 9 additions & 9 deletions MKL.NET.Optimization/Optimize.Minimum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ static double Minimum_BiSection(double atol, double rtol, double a, double b, do

const double GOLD = 0.381966011250105;

/// <summary>Minmimum estimate using golden section a &lt; b &lt; c.</summary>
/// <summary>Minimum estimate using golden section a &lt; b &lt; c.</summary>
/// <param name="a">First input.</param>
/// <param name="b">Middle input.</param>
/// <param name="c">Third input.</param>
/// <returns>Golden section of the three inputs.</returns>
public static double Minimum_GoldenSection(double a, double b, double c)
=> b - a >= c - b ? b + (a - b) * GOLD : b + (c - b) * GOLD;

/// <summary>Minmimum estimate using factor section a &lt; b &lt; c.</summary>
/// <summary>Minimum estimate using factor section a &lt; b &lt; c.</summary>
/// <param name="a">First input.</param>
/// <param name="b">Middle input.</param>
/// <param name="c">Third input.</param>
Expand All @@ -62,7 +62,7 @@ public static double Minimum_FactorSection(double a, double b, double c, double
=> b - a >= c - b ? b + (a - b) * factor : b + (c - b) * factor;

/// <summary>
/// Minimum estmate using quadratic interpolation, falling back to golden section.
/// Minimum estimate using quadratic interpolation, falling back to golden section.
/// </summary>
/// <param name="a">First function input.</param>
/// <param name="fa">First function output.</param>
Expand All @@ -73,12 +73,12 @@ public static double Minimum_FactorSection(double a, double b, double c, double
/// <returns>The minimum estimate.</returns>
public static double Minimum_Quadratic(double a, double fa, double b, double fb, double c, double fc)
{
var x = b - 0.5 * (Sqr(b - a) * (fb - fc) - Sqr(b - c) * (fb - fa)) / ((b - a) * (fb - fc) - (b - c) * (fb - fa));
var x = b - (Sqr(b - a) * (fb - fc) - Sqr(b - c) * (fb - fa)) * 0.5 / ((b - a) * (fb - fc) - (b - c) * (fb - fa));
return double.IsNaN(x) ? Minimum_GoldenSection(a, b, c) : x;
}

/// <summary>
/// Minimum estmate between a and c using cubic interpolation, falling back to quadratic then golden interpolation a &lt; b &lt; c.
/// Minimum estimate between a and c using cubic interpolation, falling back to quadratic then golden interpolation a &lt; b &lt; c.
/// See <see href="https://en.wikipedia.org/wiki/Lagrange_polynomial">Lagrange polynomial</see> and
/// <see href="https://www.themathdoctors.org/max-and-min-of-a-cubic-without-calculus/">Cubic max and min</see>.
/// </summary>
Expand Down Expand Up @@ -228,7 +228,7 @@ static void Minimum_Bracket_Fa(double atol, double rtol, Func<double, double> f,
/// <param name="fb">f(b) output.</param>
/// <param name="c">c output.</param>
/// <param name="fc">f(c) output.</param>
/// <param name="d">Additonal outer point d &lt; a or d &gt; c. Can be infinity if no more than three function evaluations are needed.</param>
/// <param name="d">Additional outer point d &lt; a or d &gt; c. Can be infinity if no more than three function evaluations are needed.</param>
/// <param name="fd">f(d) output. Can be zero if no more than three function evaluations are needed.</param>
/// <param name="lower"></param>
/// <param name="upper"></param>
Expand All @@ -248,11 +248,11 @@ public static void Minimum_Bracket(double atol, double rtol, Func<double, double
/// <param name="f">The function to find the minimum of.</param>
/// <param name="a">The first function input.</param>
/// <param name="fa">f(a) input.</param>
/// <param name="b">The second funtion input and also the minimum.</param>
/// <param name="b">The second function input and also the minimum.</param>
/// <param name="fb">f(b) input.</param>
/// <param name="c">The third function input.</param>
/// <param name="fc">f(c) input.</param>
/// <param name="d">Additonal outer point d &lt; a or d &gt; c.</param>
/// <param name="d">Additional outer point d &lt; a or d &gt; c.</param>
/// <param name="fd">f(d) input.</param>
/// <param name="cancellationToken"></param>
/// <returns>The minimum input point accurate to tol = atol + rtol * x.</returns>
Expand Down Expand Up @@ -363,7 +363,7 @@ public static double Minimum(double atol, double rtol, Func<double, double> f, d
/// <param name="rtol">The relative tolerance of the minimum position required.</param>
/// <param name="f">The function to find the minimum of.</param>
/// <param name="a">The first function input.</param>
/// <param name="b">The second funtion input and also the minimum.</param>
/// <param name="b">The second function input and also the minimum.</param>
/// <param name="c">The third function input.</param>
/// <returns>The minimum input point accurate to tol = atol + rtol * x.</returns>
public static double Minimum_Brent(double atol, double rtol, Func<double, double> f, double a, double b, double c)
Expand Down
64 changes: 38 additions & 26 deletions MKL.NET.Optimization/Optimize.Root.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace MKLNET;

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

/// <summary>Optimization and root finding algorithms.</summary>
Expand All @@ -35,7 +36,7 @@ public static bool Root_Is_Bracketed(double fa, double fb)
static double Bisect(double a, double b)
=> (a + b) * 0.5;

/// <summary>Root estmate using linear interpolation. Also called false position or regula falsi.</summary>
/// <summary>Root estimate using linear interpolation. Also called false position or regula falsi.</summary>
/// <param name="a">First function input.</param>
/// <param name="fa">First function output.</param>
/// <param name="b">Second function input.</param>
Expand All @@ -48,7 +49,7 @@ public static double Root_Linear(double a, double fa, double b, double fb)
}

/// <summary>
/// Root estmate between a and b using quadratic interpolation, falling back to linear interpolation.
/// Root estimate between a and b using quadratic interpolation, falling back to linear interpolation.
/// See <see href="https://en.wikipedia.org/wiki/Muller%27s_method">Muller's method</see>.
/// </summary>
/// <param name="a">First function input.</param>
Expand All @@ -60,18 +61,25 @@ public static double Root_Linear(double a, double fa, double b, double fb)
/// <returns>The root estimate between a and b.</returns>
public static double Root_Quadratic(double a, double fa, double b, double fb, double c, double fc)
{
Debug.Assert(fa * fb < 0, "fa and fb must bound a root");
if (Math.Abs(fb) < Math.Abs(fa))
(a, fa, b, fb) = (b, fb, a, fa);
var r = (fb - fa) / (b - a) - (fc - fb) / (c - b);
var w = (fc - fa) / (c - a) + r;
r = Math.Sqrt(w * w - 4 * fa * r / (a - c));
var x = a - 2 * fa / (w + r);
if (a < x && x < b) return x;
x = a - 2 * fa / (w - r);
if (a < x && x < b) return x;
r = w * w - fa * 4 * r / (a - c);
if (r >= 0)
{
r = Math.Sqrt(r);
var x = a - fa * 2 / (w + r);
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
x = a - fa * 2 / (w - r);
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
}
return Root_Linear(a, fa, b, fb); // Rounding errors, it must be near a or b, Root_Linear will work.
}

/// <summary>
/// Root estmate between a and b using inverse quadratic interpolation, falling back to quadratic then linear interpolation.
/// Root estimate between a and b using inverse quadratic interpolation, falling back to quadratic then linear interpolation.
/// See <see href="https://en.wikipedia.org/wiki/Inverse_quadratic_interpolation">Inverse quadratic interpolation</see>.
/// </summary>
/// <param name="a">First function input.</param>
Expand All @@ -98,7 +106,7 @@ public static double Root_InverseQuadratic(double a, double fa, double b, double
#endif

/// <summary>
/// Root estmate between a and b using cubic interpolation, falling back to quadratic then linear interpolation.
/// Root estimate between a and b using cubic interpolation, falling back to quadratic then linear interpolation.
/// See <see href="https://en.wikipedia.org/wiki/Lagrange_polynomial">Lagrange polynomial</see> and
/// <see href="https://mathworld.wolfram.com/CubicFormula.html">Cubic formula</see>.
/// </summary>
Expand All @@ -113,6 +121,7 @@ public static double Root_InverseQuadratic(double a, double fa, double b, double
/// <returns>The root estimate between a and b.</returns>
public static double Root_Cubic(double a, double fa, double b, double fb, double c, double fc, double d, double fd)
{
Debug.Assert(fa * fb < 0, "fa and fb must bound a root");
// https://en.wikipedia.org/wiki/Lagrange_polynomial
var a0 = -fa * (b * c * d) / ((a - b) * (a - c) * (a - d)) - fb * (a * c * d) / ((b - a) * (b - c) * (b - d)) - fc * (a * b * d) / ((c - a) * (c - b) * (c - d)) - fd * (a * b * c) / ((d - a) * (d - b) * (d - c));
var a1 = fa * (b * c + b * d + c * d) / ((a - b) * (a - c) * (a - d)) + fb * (a * c + a * d + c * d) / ((b - a) * (b - c) * (b - d)) + fc * (a * b + a * d + b * d) / ((c - a) * (c - b) * (c - d)) + fd * (a * b + a * c + b * c) / ((d - a) * (d - b) * (d - c));
Expand All @@ -121,40 +130,43 @@ public static double Root_Cubic(double a, double fa, double b, double fb, double
a0 /= a3; a1 /= a3; a2 /= a3;

// https://mathworld.wolfram.com/CubicFormula.html
var Q = (3 * a1 - a2 * a2) / 9;
var R = (9 * a2 * a1 - 27 * a0 - 2 * a2 * a2 * a2) / 54;
var Q = (a1 * 3 - a2 * a2) / 9;
var R = (a2 * a1 * 9 - a0 * 27 - a2 * a2 * a2 * 2) / 54;
var Q3 = Q * Q * Q;
var D = Q3 + R * R;
var shift = a2 / -3;
if (D < 0)
{
var theta = Math.Acos(R / Math.Sqrt(-Q3));
var x = 2 * Math.Sqrt(-Q) * Math.Cos(theta / 3) + shift;
if (a < x && x < b) return x;
x = 2 * Math.Sqrt(-Q) * Math.Cos((theta + Math.PI * 2) / 3) + shift;
if (a < x && x < b) return x;
x = 2 * Math.Sqrt(-Q) * Math.Cos((theta - Math.PI * 2) / 3) + shift;
if (a < x && x < b) return x;
var x = Math.Sqrt(-Q) * Math.Cos(theta / 3) * 2 + shift;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
x = Math.Sqrt(-Q) * Math.Cos((theta + Math.PI * 2) / 3) * 2 + shift;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
x = Math.Sqrt(-Q) * Math.Cos((theta - Math.PI * 2) / 3) * 2 + shift;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
}
else if (D == 0)
{
var S = Cbrt(R);
var x = shift + 2 * S;
if (a < x && x < b) return x;
var x = shift + S * 2;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
x = shift - S;
if (a < x && x < b) return x;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
}
else
{
var sqrtD = Math.Sqrt(D);
var x = Cbrt(R + sqrtD) + Cbrt(R - sqrtD) + shift;
if (a < x && x < b) return x;
if (a < b && a < x && x < b || a > b && a > x && x > b) return x;
}
return Root_Quadratic(a, fa, b, fb, c, fc);
}

return Math.Min(Math.Abs(c - a), Math.Abs(c - b)) <= Math.Min(Math.Abs(d - a), Math.Abs(d - b))
? Root_Quadratic(a, fa, b, fb, c, fc)
: Root_Quadratic(a, fa, b, fb, d, fd);
} // TODO: Possibly a Hermite spline is better especially when a cubic overshoots and has a max and a min

/// <summary>
/// Root estmate between a and b using inverse cubic interpolation, falling back to inverse quadratic, quadratic then linear interpolation.
/// Root estimate between a and b using inverse cubic interpolation, falling back to inverse quadratic, quadratic then linear interpolation.
/// </summary>
/// <param name="a">First function input.</param>
/// <param name="fa">First function output.</param>
Expand Down Expand Up @@ -199,11 +211,11 @@ public static double Root_Halley(double x, double fx, double df_dx, double d2f_d
=> x - fx / (df_dx - 0.5 * fx / df_dx * d2f_dx2);

/// <summary>
/// The tolarance calculated at a point.
/// The tolerance calculated at a point.
/// </summary>
/// <param name="atol">The absolute tolerance.</param>
/// <param name="rtol">The relative tolerance.</param>
/// <param name="x">The point at which to calcuate the tolerance.</param>
/// <param name="x">The point at which to calculate the tolerance.</param>
/// <returns>tol = atol + rtol * x</returns>
public static double Tol(double atol, double rtol, double x)
=> atol + rtol * Math.Abs(x);
Expand Down
2 changes: 1 addition & 1 deletion MKL.NET.Statistics/HistogramEstimator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void Add(double s)

for (int i = 1; i < n.Length - 1; i++)
{
var d = (n[n.Length - 1] - n[0]) * (double)i / (n.Length - 1) + n[0] - n[i];
var d = (n[n.Length - 1] - 1) * (double)i / (n.Length - 1) + 1 - n[i];
if (d >= 1.0 && n[i + 1] - n[i] > 1)
{
var h = n[i + 1] - n[i];
Expand Down
Loading

0 comments on commit 74e0750

Please sign in to comment.