From fe62617bebf809f1500f06c0046177fe48372fab Mon Sep 17 00:00:00 2001 From: dvdrw Date: Mon, 25 Nov 2024 14:44:01 +0100 Subject: [PATCH] chore: add comments to swarm.hpp --- include/swarm.hpp | 29 ++++++++++++++++++++++++++++- src/main.cpp | 10 ++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/swarm.hpp b/include/swarm.hpp index 4c3ff26..92454f0 100644 --- a/include/swarm.hpp +++ b/include/swarm.hpp @@ -8,13 +8,37 @@ #include #include +/** + * An Agent in a Particle Swarm Optimisation simulation. + * #T is the type of the position vector the Agent uses. + */ template struct Agent { + /** + * Type of the fitness function. + */ using F = std::function; + /** + * Moves the Agent along its velocity by a factor of #dt. + * + * The parameter #dt is useful when drawing the Agent moving faster than it + * #tick()s. + * + * @see: step() + */ virtual void move(float dt) = 0; + + /** + * Steps the algorithm values one tick forward. + * Warning: Does not move the Agent. Use #move() for this + * @see: move() + */ virtual void step() = 0; + /** + * The best position this Agent has seen during its lifetime. + */ virtual std::pair best() const = 0; Agent(F f) : f(f) {} @@ -24,6 +48,8 @@ protected: template concept ParameterChangeAlgorithm = requires(A alg, float f, unsigned int i) { + // initial viscosity, initial nostalgia, initial peer pressure, current + // iteration, max iteration { alg(f, f, f, i, i) } -> std::same_as>; }; @@ -62,13 +88,14 @@ namespace ParamChange { }; }; -template> +template struct Particle : public Agent> { std::pair> best() const override { return {pb, pb_pos}; }; void move(float dt=1) override { position = position + velocity * dt; } void step() override { + // Get the new parameter values vec<3> params = alg(kviscosity, knostalgia, kpeer_pressure, curr_iter, max_iter); diff --git a/src/main.cpp b/src/main.cpp index 56d3a74..c916358 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,12 +65,21 @@ main(int argc, char **argv) { scr.draw(); }; + // We draw to the screen at a rate of `kFPS', but step()ing the swarm at + // this rate would be far too fast to be interesting to look at. On the + // other hand, step()ing once a second is too slow. + // + // So, we step() every quarter second. To line up the move() so that a unit + // move() happens preceding each step(), we also need to move as fast as + // we've shortened our step() interval. for(int i = 0; i < iter_count * kFPS/4;) { if(!pause) { scr.clear(); update_and_draw(); + // Since we step() 4x a second, we need to move() 4x as fast as moving by dt + // each frame. swarm.move(kDT * 4); if(i % (kFPS/4) == (kFPS/4)-1) swarm.step(); @@ -152,6 +161,7 @@ main(int argc, char **argv) { break; } + // Wait for kDT (time between two frames) usleep(1000 * 1000 / kFPS); }