Predictive scanning implemented for bydivisor method.
This commit is contained in:
1 parent
ef8034b258
commit
a6d408f2aa
10 files changed
+1562
-40
No files matched your search
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using FluentAssertions;
|
||||
using PerfectNumbers.Core.ByDivisor;
|
||||
using Xunit;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace PerfectNumbers.Core.Tests;
|
||||
|
||||
public sealed class ByDivisorClassModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void LoadOrBuild_builds_model_from_results_file()
|
||||
{
|
||||
string tempPath = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
File.WriteAllLines(
|
||||
tempPath,
|
||||
new[]
|
||||
{
|
||||
"p,divisor,searchedMersenne,detailedCheck,passedAllTests",
|
||||
"5,31,true,true,false",
|
||||
"5,0,true,true,true",
|
||||
"13,8191,true,true,false",
|
||||
});
|
||||
|
||||
string modelPath = tempPath + ".model";
|
||||
ByDivisorScanTuning tuning = new()
|
||||
{
|
||||
CheapLimit = 32,
|
||||
};
|
||||
|
||||
ByDivisorClassModel model = ByDivisorClassModelLoader.LoadOrBuild(modelPath, tempPath, tuning, tuning.CheapLimit);
|
||||
|
||||
ByDivisorClassEntry classFive = model.Entries[5];
|
||||
classFive.K50.Should().Be(3d);
|
||||
classFive.K75.Should().Be(3d);
|
||||
classFive.GapProbability.Should().BeApproximately(0.5d, 1e-12);
|
||||
classFive.SampleCount.Should().Be(2);
|
||||
classFive.GapCount.Should().Be(1);
|
||||
|
||||
ByDivisorClassEntry classThirteen = model.Entries[13];
|
||||
classThirteen.K50.Should().Be(315d);
|
||||
classThirteen.K75.Should().Be(315d);
|
||||
classThirteen.GapProbability.Should().Be(0d);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryDelete(tempPath);
|
||||
TryDelete(tempPath + ".model");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPlan_uses_aggressive_tuning_for_hard_class()
|
||||
{
|
||||
var model = new ByDivisorClassModel
|
||||
{
|
||||
CheapLimit = 50,
|
||||
};
|
||||
model.Entries[0] = new ByDivisorClassEntry
|
||||
{
|
||||
K50 = 1000d,
|
||||
K75 = 2000d,
|
||||
GapProbability = 0.8d,
|
||||
Stability = "escaping",
|
||||
};
|
||||
|
||||
ByDivisorScanTuning tuning = new()
|
||||
{
|
||||
CheapLimit = 50,
|
||||
Gamma50 = 0.8d,
|
||||
Gamma75 = 1.2d,
|
||||
AggressiveGamma50 = 1.0d,
|
||||
AggressiveGamma75 = 1.4d,
|
||||
Rho1 = 1.35d,
|
||||
Rho2 = 1.6d,
|
||||
AggressiveRho2 = 1.8d,
|
||||
HardGapThreshold = 0.75d,
|
||||
};
|
||||
|
||||
ByDivisorScanPlan plan = model.BuildPlan(2UL, BigInteger.Zero, tuning);
|
||||
|
||||
plan.CheapLimit.Should().Be(50d);
|
||||
plan.Start.Should().Be(1000d);
|
||||
plan.Target.Should().Be(2800d);
|
||||
plan.Rho1.Should().Be(1.35d);
|
||||
plan.Rho2.Should().Be(1.8d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadOrBuild_rebuilds_when_results_newer_than_model()
|
||||
{
|
||||
string tempResults = Path.GetTempFileName();
|
||||
string tempModel = tempResults + ".model";
|
||||
try
|
||||
{
|
||||
File.WriteAllLines(
|
||||
tempResults,
|
||||
new[]
|
||||
{
|
||||
"p,divisor,searchedMersenne,detailedCheck,passedAllTests",
|
||||
"5,31,true,true,false",
|
||||
});
|
||||
|
||||
// Write a stale model
|
||||
var staleModel = new ByDivisorClassModel
|
||||
{
|
||||
CheapLimit = 10,
|
||||
};
|
||||
File.WriteAllText(tempModel, JsonSerializer.Serialize(staleModel));
|
||||
File.SetLastWriteTimeUtc(tempModel, DateTime.UtcNow.AddMinutes(-10));
|
||||
File.SetLastWriteTimeUtc(tempResults, DateTime.UtcNow);
|
||||
|
||||
ByDivisorScanTuning tuning = new()
|
||||
{
|
||||
CheapLimit = 32,
|
||||
};
|
||||
|
||||
ByDivisorClassModel model = ByDivisorClassModelLoader.LoadOrBuild(tempModel, tempResults, tuning, tuning.CheapLimit);
|
||||
|
||||
model.Entries[5].K50.Should().Be(3d);
|
||||
File.GetLastWriteTimeUtc(tempModel).Should().BeAfter(File.GetLastWriteTimeUtc(tempResults).AddSeconds(-2));
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryDelete(tempResults);
|
||||
TryDelete(tempModel);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryDelete(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore cleanup failure in tests
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user