13#include <doctest/doctest.h>
16using namespace manifolds;
18SCENARIO(
"MoveStrategy<METROPOLIS> special member and swap properties" *
19 doctest::test_suite(
"metropolis"))
22 "MoveStrategy<METROPOLIS> special member and swap properties.\n");
23 GIVEN(
"A Metropolis move strategy.")
25 WHEN(
"Special members are examined.")
27 THEN(
"It is no-throw destructible.")
29 REQUIRE(is_nothrow_destructible_v<Metropolis_3>);
30 REQUIRE(is_nothrow_destructible_v<Metropolis_4>);
31 spdlog::debug(
"It is no-throw destructible.\n");
33 THEN(
"It is no-throw default constructible.")
35 REQUIRE(is_nothrow_default_constructible_v<Metropolis_3>);
36 REQUIRE(is_nothrow_default_constructible_v<Metropolis_4>);
37 spdlog::debug(
"It is no-throw default constructible.\n");
39 THEN(
"It is no-throw copy constructible.")
41 REQUIRE(is_nothrow_copy_constructible_v<Metropolis_3>);
42 REQUIRE(is_nothrow_copy_constructible_v<Metropolis_4>);
43 spdlog::debug(
"It is no-throw copy constructible.\n");
45 THEN(
"It is no-throw copy assignable.")
47 REQUIRE(is_nothrow_copy_assignable_v<Metropolis_3>);
48 REQUIRE(is_nothrow_copy_assignable_v<Metropolis_4>);
49 spdlog::debug(
"It is no-throw copy assignable.\n");
51 THEN(
"It is no-throw move constructible.")
53 REQUIRE(is_nothrow_move_constructible_v<Metropolis_3>);
54 REQUIRE(is_nothrow_move_constructible_v<Metropolis_4>);
55 spdlog::debug(
"It is no-throw move constructible.\n");
57 THEN(
"It is no-throw move assignable.")
59 REQUIRE(is_nothrow_move_assignable_v<Metropolis_3>);
60 REQUIRE(is_nothrow_move_assignable_v<Metropolis_4>);
61 spdlog::debug(
"It is no-throw move assignable.\n");
63 THEN(
"It is no-throw swappable.")
65 REQUIRE(is_nothrow_swappable_v<Metropolis_3>);
66 REQUIRE(is_nothrow_swappable_v<Metropolis_4>);
67 spdlog::debug(
"It is no-throw swappable.\n");
69 THEN(
"It is constructible from 5 parameters.")
71 REQUIRE(is_constructible_v<
Metropolis_3,
long double,
long double,
73 REQUIRE(is_constructible_v<
Metropolis_4,
long double,
long double,
75 spdlog::debug(
"It is constructible from 5 parameters.\n");
81SCENARIO(
"Metropolis member functions" * doctest::test_suite(
"metropolis"))
83 auto constexpr Alpha =
static_cast<long double>(0.6);
84 auto constexpr K =
static_cast<long double>(1.1);
85 auto constexpr Lambda =
static_cast<long double>(0.1);
86 GIVEN(
"A correctly-constructed Manifold_3.")
88 auto constexpr simplices = 640;
89 auto constexpr timeslices = 4;
90 Manifold_3 const universe(simplices, timeslices);
92 REQUIRE(universe.is_correct());
93 WHEN(
"A Metropolis function object is constructed.")
95 auto constexpr output_every_n_passes = 1;
96 auto constexpr passes = 10;
97 Metropolis_3 testrun(Alpha, K, Lambda, passes, output_every_n_passes);
98 THEN(
"The Metropolis function object is initialized correctly.")
100 CHECK_EQ(testrun.Alpha(), Alpha);
101 CHECK_EQ(testrun.K(), K);
102 CHECK_EQ(testrun.Lambda(), Lambda);
103 CHECK_EQ(testrun.passes(), passes);
104 CHECK_EQ(testrun.checkpoint(), output_every_n_passes);
105 CHECK_EQ(testrun.get_proposed().total(), 0);
106 CHECK_EQ(testrun.get_accepted().total(), 0);
107 CHECK_EQ(testrun.get_rejected().total(), 0);
108 CHECK_EQ(testrun.get_attempted().total(), 0);
109 CHECK_EQ(testrun.get_succeeded().total(), 0);
110 CHECK_EQ(testrun.get_failed().total(), 0);
112 THEN(
"The initial moves are made correctly.")
114 auto result = testrun.initialize(universe);
115 auto total_rejected = testrun.get_rejected().total();
116 auto total_attempted = testrun.get_attempted().total();
117 auto total_successful = testrun.get_succeeded().total();
118 auto total_failed = testrun.get_failed().total();
120 for (
auto i = 0; i < move_tracker::NUMBER_OF_3D_MOVES; ++i)
122 CHECK_EQ(testrun.get_proposed()[i], 1);
125 for (
auto i = 0; i < move_tracker::NUMBER_OF_3D_MOVES; ++i)
127 CHECK_EQ(testrun.get_accepted()[i], 1);
130 CHECK_EQ(total_rejected, 0);
132 for (
auto i = 0; i < move_tracker::NUMBER_OF_3D_MOVES; ++i)
134 CHECK_EQ(testrun.get_attempted()[i], 1);
136 CHECK_EQ(total_attempted, total_successful + total_failed);
139 REQUIRE_MESSAGE(result,
140 "The Metropolis function object failed to "
141 "initialize the universe.");
144 result->print_attempts();
145 result->print_successful();
146 result->print_errors();
153SCENARIO(
"Using the Metropolis algorithm" * doctest::test_suite(
"metropolis"))
155 auto constexpr Alpha =
static_cast<long double>(0.6);
156 auto constexpr K =
static_cast<long double>(1.1);
157 auto constexpr Lambda =
static_cast<long double>(0.1);
158 GIVEN(
"A correctly-constructed Manifold_3.")
160 auto constexpr simplices = 640;
161 auto constexpr timeslices = 4;
162 Manifold_3 const universe(simplices, timeslices);
164 REQUIRE(universe.is_correct());
165 WHEN(
"A Metropolis function object is constructed.")
167 auto constexpr output_every_n_passes = 1;
168 auto constexpr passes = 1;
169 Metropolis_3 testrun(Alpha, K, Lambda, passes, output_every_n_passes);
170 THEN(
"A lot of moves are done.")
172 auto result = testrun(universe);
174 CHECK(result.is_valid());
175 AND_THEN(
"The correct number of moves are attempted.")
177 auto total_proposed = testrun.get_proposed().total();
178 auto total_accepted = testrun.get_accepted().total();
179 auto total_rejected = testrun.get_rejected().total();
180 auto total_attempted = testrun.get_attempted().total();
181 auto total_successful = testrun.get_succeeded().total();
182 auto total_failed = testrun.get_failed().total();
185 CHECK_GT(total_proposed, universe.N3() * passes);
186 CHECK_EQ(total_proposed, total_accepted + total_rejected);
188 CHECK_EQ(total_attempted, total_accepted);
189 CHECK_GT(total_successful, 0);
190 CHECK_GE(total_failed, 0);
191 CHECK_EQ(total_attempted, total_successful + total_failed);
193 testrun.print_results();
Perform Metropolis-Hastings algorithm on Delaunay Triangulations.
std::int_fast32_t Int_precision
SCENARIO("Perform bistellar flip on Delaunay triangulation" *doctest::test_suite("bistellar"))