CDT++
Causal Dynamical Triangulations in C++
Loading...
Searching...
No Matches
Move_command.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 Causal Dynamical Triangulations in C++ using CGAL
3
4 Copyright © 2018 Adam Getchell
5 ******************************************************************************/
6
10
11#ifndef CDT_PLUSPLUS_MOVECOMMAND_HPP
12#define CDT_PLUSPLUS_MOVECOMMAND_HPP
13
14#include "Apply_move.hpp"
15#include "Ergodic_moves_3.hpp"
16
17template <typename ManifoldType,
18 typename ExpectedType = std::expected<ManifoldType, std::string>,
19 typename FunctionType = tl::function_ref<ExpectedType(ManifoldType&)>>
21{
22 using Queue = std::deque<move_tracker::move_type>;
24
28 ManifoldType m_manifold;
29
33 Queue m_moves;
34
39
44
49
54
55 public:
59 MoveCommand() = delete;
60
68 explicit MoveCommand(ManifoldType t_manifold)
69 : m_manifold{std::move(t_manifold)}
70 {}
71
75 auto get_const_results() const -> ManifoldType const&
76 {
77 return std::cref(m_manifold);
78 } // get_const_results
79
83 [[nodiscard]] auto get_results() -> ManifoldType& { return m_manifold; }
84
88 [[nodiscard]] auto get_attempted() const -> Counter const&
89 {
90 return m_attempted;
91 } // get_attempts
92
96 [[nodiscard]] auto get_succeeded() const
97 {
98 return m_succeeded;
99 } // get_succeeded
100
104 [[nodiscard]] auto get_failed() const -> Counter const&
105 {
106 return m_failed;
107 } // get_errors
108
113 {
116 m_failed.reset();
117 }
118
124 {
125 m_moves.push_front(t_move);
126 }
127
131 auto size() const { return m_moves.size(); }
132
136 void execute()
137 {
138#ifndef NDEBUG
139 fmt::print("=== Executing: Before moves ===\n");
140 m_manifold.print_details();
141 fmt::print("===============================\n");
142#endif
143
144 while (!m_moves.empty())
145 {
146 auto move_type = m_moves.back();
147 // Record attempted move
148 ++m_attempted[as_integer(move_type)];
149 // Convert move_type to function
150 auto move_function = as_move_function(move_type);
151 // Execute move
152 if (auto result = apply_move(m_manifold, move_function); result)
153 {
154 result->update();
155 swap(result.value(), m_manifold);
156 ++m_succeeded[as_integer(move_type)];
157 }
158 else
159 {
160 fmt::print("{}\n", result.error());
161 // Track failed moves
162 ++m_failed[as_integer(move_type)];
163 m_moves_to_retry.push_front(move_type);
164 }
165 // Remove move from queue
166 m_moves.pop_back();
167 }
168#ifndef NDEBUG
169 fmt::print("=== After moves ===\n");
171 print_errors();
172 m_manifold.print_details();
173 fmt::print("===================\n");
174#endif
175 } // execute
176
183 -> FunctionType
184 {
185 switch (move)
186 {
187 case move_tracker::move_type::TWO_THREE: return ergodic_moves::do_23_move;
188 case move_tracker::move_type::THREE_TWO: return ergodic_moves::do_32_move;
189 case move_tracker::move_type::TWO_SIX: return ergodic_moves::do_26_move;
190 case move_tracker::move_type::SIX_TWO: return ergodic_moves::do_62_move;
191 default: return ergodic_moves::do_44_move;
192 }
193 } // move_function
194
198 void print_attempts() const
199 {
200 if (ManifoldType::dimension == 3)
201 {
202 fmt::print(
203 "There were {} attempted (2,3) moves and {} attempted (3,2) moves "
204 "and {} "
205 "attempted (2,6) moves and {} attempted (6,2) moves and {} attempted "
206 "(4,4) "
207 "moves.\n",
211 }
212 else
213 {
214 // 4D
215 fmt::print(
216 "There were {} attempted (2,4) moves and {} attempted (4,2) moves "
217 "and {} "
218 "attempted (3,3) moves and {} attempted (4,6) moves and {} attempted "
219 "(6,4) "
220 "moves and {} attempted (2,8) moves and {} attempted (8,2) moves.\n",
225 }
226 }
227
231 void print_successful() const
232 {
233 if (ManifoldType::dimension == 3)
234 {
235 fmt::print(
236 "There were {} successful (2,3) moves and {} successful (3,2) moves "
237 "and {} "
238 "successful (2,6) moves and {} successful (6,2) moves and {} "
239 "successful "
240 "(4,4) "
241 "moves.\n",
245 }
246 else
247 {
248 // 4D
249 fmt::print(
250 "There were {} successful (2,4) moves and {} successful (4,2) moves "
251 "and {} "
252 "successful (3,3) moves and {} successful (4,6) moves and {} "
253 "successful "
254 "(6,4) "
255 "moves and {} successful (2,8) moves and {} successful (8,2) "
256 "moves.\n",
261 }
262 }
263
267 void print_errors() const
268 {
269 if (std::all_of(m_failed.moves_view().begin(), m_failed.moves_view().end(),
270 [](auto const& value) { return value == 0; }))
271 {
272 fmt::print("There were no failed moves.\n");
273 }
274 else
275 {
276 if (ManifoldType::dimension == 3)
277 {
278 fmt::print(
279 "There were {} failed (2,3) moves and {} failed (3,2) moves and {} "
280 "failed (2,6) moves and {} failed (6,2) moves and {} failed (4,4) "
281 "moves.\n",
285 }
286 else
287 {
288 // 4D
289 fmt::print(
290 "There were {} failed (2,4) moves and {} failed (4,2) moves and {} "
291 "failed (3,3) moves and {} failed (4,6) moves and {} failed (6,4) "
292 "moves and {} failed (2,8) moves and {} failed (8,2) moves.\n",
297 }
298 }
299 }
300};
301
302#endif // CDT_PLUSPLUS_MOVECOMMAND_HPP
Apply Pachner moves to foliated Delaunay triangulations.
auto constexpr apply_move(ManifoldType &&t_manifold, FunctionType t_move) noexcept -> decltype(auto)
An applicative function similar to std::apply on a manifold.
Definition: Apply_move.hpp:32
Pachner moves on 2+1 dimensional foliated Delaunay triangulations.
move_type
The types of 3D ergodic moves.
void execute()
Execute all moves in the queue on the manifold.
ManifoldType m_manifold
The manifold on which to perform moves.
void reset_counters()
Reset counters.
MoveCommand(ManifoldType t_manifold)
MoveCommand ctor.
auto get_attempted() const -> Counter const &
Attempted moves by MoveCommand.
auto get_results() -> ManifoldType &
Results of the moves invoked by MoveCommand.
void print_attempts() const
Print attempted moves.
Counter m_succeeded
The counter of successful moves.
void print_errors() const
Print move errors.
auto get_failed() const -> Counter const &
Failed moves by MoveCommand.
Counter m_attempted
The counter of attempted moves.
static auto as_move_function(move_tracker::move_type const move) -> FunctionType
Execute a move function on a manifold.
auto get_succeeded() const
Successful moves by MoveCommand.
MoveCommand()=delete
Remove default ctor.
void print_successful() const
Print successful moves.
auto get_const_results() const -> ManifoldType const &
A read-only reference to the manifold.
Counter m_failed
The counter of failed moves.
Queue m_moves
The queue of moves to perform.
void enqueue(move_tracker::move_type const t_move)
Push a Pachner move onto the move queue.
Queue m_moves_to_retry
The queue of moves to retry.
auto size() const
The number of moves on the queue.
The data and methods to track ergodic moves.
auto two_six_moves() -> auto &
Write access to (2,6) moves.
auto three_three_moves() -> auto &
Write access to (3,3) moves.
auto two_eight_moves() -> auto &
Write access to (2,8) moves.
auto two_four_moves() -> auto &
Write access to (2,4) moves.
auto four_six_moves() -> auto &
Write access to (4,6) moves.
auto four_two_moves() -> auto &
Write access to (4,2) moves.
auto moves_view() const
Get a view of the moves.
auto four_four_moves() -> auto &
Write access to (4,4) moves.
auto six_four_moves() -> auto &
Write access to (6,4) moves.
auto eight_two_moves() -> auto &
Write access to (8,2) moves.
void reset()
Reset all moves counts to zero.
auto six_two_moves() -> auto &
Write access to (6,2) moves.
auto three_two_moves() -> auto &
Write access to (3,2) moves.
auto two_three_moves() -> auto &
Write access to (2,3) moves.