Skip to content

Commit 1bb9cfc

Browse files
committed
Add unit tests for PdfSampler
1 parent 86d4393 commit 1bb9cfc

1 file changed

Lines changed: 148 additions & 0 deletions

File tree

tests/src/test_pdf_sampler.cpp

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include <gtest/gtest.h>
2+
3+
#include "highmap.hpp"
4+
5+
using namespace hmap;
6+
7+
TEST(PdfSampler, SampleReturnsValueInUnitInterval)
8+
{
9+
std::vector<float> pdf = {1.f, 1.f, 1.f, 1.f};
10+
11+
PdfSampler sampler(pdf, 42);
12+
13+
for (int i = 0; i < 1000; ++i)
14+
{
15+
float s = sampler.sample();
16+
17+
EXPECT_GE(s, 0.f);
18+
EXPECT_LT(s, 1.f);
19+
}
20+
}
21+
22+
TEST(PdfSampler, SampleVectorSize)
23+
{
24+
std::vector<float> pdf = {1.f, 2.f, 3.f};
25+
26+
PdfSampler sampler(pdf, 42);
27+
28+
std::vector<float> samples = sampler.sample(128);
29+
30+
EXPECT_EQ(samples.size(), 128);
31+
}
32+
33+
TEST(PdfSampler, DeterministicWithSameSeed)
34+
{
35+
std::vector<float> pdf = {1.f, 2.f, 3.f, 4.f};
36+
37+
PdfSampler s0(pdf, 1234);
38+
PdfSampler s1(pdf, 1234);
39+
40+
for (int i = 0; i < 100; ++i)
41+
{
42+
float a = s0.sample();
43+
float b = s1.sample();
44+
45+
EXPECT_FLOAT_EQ(a, b);
46+
}
47+
}
48+
49+
TEST(PdfSampler, DifferentSeedsProduceDifferentSequences)
50+
{
51+
std::vector<float> pdf = {1.f, 2.f, 3.f, 4.f};
52+
53+
PdfSampler s0(pdf, 1);
54+
PdfSampler s1(pdf, 2);
55+
56+
bool different = false;
57+
58+
for (int i = 0; i < 50; ++i)
59+
{
60+
if (s0.sample() != s1.sample())
61+
{
62+
different = true;
63+
break;
64+
}
65+
}
66+
67+
EXPECT_TRUE(different);
68+
}
69+
70+
TEST(PdfSampler, UniformPdfProducesUniformBins)
71+
{
72+
std::vector<float> pdf = {1.f, 1.f, 1.f, 1.f};
73+
74+
PdfSampler sampler(pdf, 42);
75+
76+
const int nsamples = 20000;
77+
78+
std::vector<int> bins(4, 0);
79+
80+
for (int i = 0; i < nsamples; ++i)
81+
{
82+
float s = sampler.sample();
83+
84+
int k = std::min(3, static_cast<int>(s * 4.f));
85+
86+
bins[k]++;
87+
}
88+
89+
float expected = static_cast<float>(nsamples) / 4.f;
90+
91+
for (int c : bins)
92+
EXPECT_NEAR(static_cast<float>(c), expected, 0.1f * expected);
93+
}
94+
95+
TEST(PdfSampler, WeightedPdfFavorsLargerBins)
96+
{
97+
std::vector<float> pdf = {1.f, 1.f, 10.f, 1.f};
98+
99+
PdfSampler sampler(pdf, 42);
100+
101+
const int nsamples = 20000;
102+
103+
std::vector<int> bins(4, 0);
104+
105+
for (int i = 0; i < nsamples; ++i)
106+
{
107+
float s = sampler.sample();
108+
109+
int k = std::min(3, static_cast<int>(s * 4.f));
110+
111+
bins[k]++;
112+
}
113+
114+
EXPECT_GT(bins[2], bins[0]);
115+
EXPECT_GT(bins[2], bins[1]);
116+
EXPECT_GT(bins[2], bins[3]);
117+
}
118+
119+
TEST(PdfSampler, SingleBinAlwaysSamplesInsideBin)
120+
{
121+
std::vector<float> pdf = {1.f};
122+
123+
PdfSampler sampler(pdf, 42);
124+
125+
for (int i = 0; i < 100; ++i)
126+
{
127+
float s = sampler.sample();
128+
129+
EXPECT_GE(s, 0.f);
130+
EXPECT_LT(s, 1.f);
131+
}
132+
}
133+
134+
TEST(PdfSampler, SampleVectorDeterministic)
135+
{
136+
std::vector<float> pdf = {1.f, 2.f, 3.f};
137+
138+
PdfSampler s0(pdf, 99);
139+
PdfSampler s1(pdf, 99);
140+
141+
std::vector<float> v0 = s0.sample(256);
142+
std::vector<float> v1 = s1.sample(256);
143+
144+
ASSERT_EQ(v0.size(), v1.size());
145+
146+
for (size_t i = 0; i < v0.size(); ++i)
147+
EXPECT_FLOAT_EQ(v0[i], v1[i]);
148+
}

0 commit comments

Comments
 (0)