Skip to content

Commit d2366cb

Browse files
committed
Add a class for tracking noise in row counts.
1 parent eb19651 commit d2366cb

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

src/explorer/Common/NoisyCount.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
namespace Explorer.Common
2+
{
3+
using System;
4+
5+
internal struct NoisyCount : IEquatable<NoisyCount>
6+
{
7+
private NoisyCount(long count, double variance)
8+
{
9+
Count = count;
10+
Variance = variance;
11+
}
12+
13+
public static NoisyCount Zero => default;
14+
15+
public long Count { get; private set; }
16+
17+
public double Variance { get; private set; }
18+
19+
public double Noise => Math.Sqrt(Variance);
20+
21+
public static bool operator ==(NoisyCount left, NoisyCount right) => left.Equals(right);
22+
23+
public static bool operator !=(NoisyCount left, NoisyCount right) => !(left == right);
24+
25+
public static NoisyCount operator +(NoisyCount left, NoisyCount right) => left.Add(right);
26+
27+
public static NoisyCount Noiseless(long count) => new NoisyCount(count, 0);
28+
29+
public static NoisyCount WithNoise(long count, double noise) => new NoisyCount(count, noise * noise);
30+
31+
public static NoisyCount WithVariance(long count, double variance) => new NoisyCount(count, variance);
32+
33+
public static NoisyCount FromCountableRow(CountableRow row) => WithNoise(row.Count, row.CountNoise ?? 0.0);
34+
35+
public NoisyCount Add(NoisyCount other) => new NoisyCount(Count + other.Count, Variance + other.Variance);
36+
37+
public void Add(long count, double noise)
38+
{
39+
Count += count;
40+
Variance += noise * noise;
41+
}
42+
43+
public void Add(CountableRow row)
44+
{
45+
Add(row.Count, row.CountNoise ?? 0.0);
46+
}
47+
48+
public override bool Equals(object? obj)
49+
{
50+
return obj is NoisyCount other && Equals(other);
51+
}
52+
53+
public override int GetHashCode()
54+
{
55+
return HashCode.Combine(Count, Variance);
56+
}
57+
58+
public bool Equals(NoisyCount other) =>
59+
Count == other.Count && Variance == other.Variance;
60+
}
61+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace Explorer.Common.Tests
2+
{
3+
using Explorer.Common;
4+
using Xunit;
5+
6+
public sealed class NoisyCountTests
7+
{
8+
[Fact]
9+
public void ZeroIsZero()
10+
{
11+
var zero = NoisyCount.Zero;
12+
Assert.True(zero.Count == 0);
13+
Assert.True(zero.Variance == 0);
14+
Assert.True(zero.Noise == 0);
15+
Assert.True(zero == NoisyCount.Zero);
16+
}
17+
18+
[Theory]
19+
[InlineData(100, 1.4)]
20+
[InlineData(40, 4.3)]
21+
public void AddingZeroDoesNothing(long count, double noise)
22+
{
23+
var nc = NoisyCount.WithNoise(count, noise);
24+
var result = NoisyCount.Zero + nc;
25+
Assert.True(result == nc);
26+
}
27+
28+
[Fact]
29+
public void NoiseValuesCombinedCorrectly()
30+
{
31+
var a = NoisyCount.WithNoise(100, 3);
32+
var b = NoisyCount.WithNoise(200, 4);
33+
var expected = NoisyCount.WithNoise(300, 5);
34+
35+
var result = a + b;
36+
Assert.True(result == expected);
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)