Baseline Flop Count Update, New Float Baseline
This commit is contained in:
committed by
Ahmed Kallala
parent
40f4421d60
commit
43e54871df
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
#include "vector2d_float.hpp"
|
||||
|
||||
struct Obstacle {
|
||||
Vector2d start; // First endpoint of the obstacle segment.
|
||||
Vector2d end; // Second endpoint of the obstacle segment.
|
||||
Vector2d obstacle_v; // Direction vector of the segment: end - start.
|
||||
float length_sq_inv; // Inverse squared length of the segment, used for projection.
|
||||
|
||||
// Default constructor: creates a degenerate obstacle at the origin.
|
||||
// This is mainly used for array allocation before assigning real obstacles.
|
||||
Obstacle() : start(0, 0), end(0, 0), obstacle_v(0, 0), length_sq_inv(0.0) {}
|
||||
|
||||
// Constructs an obstacle as a finite line segment from s to e.
|
||||
//
|
||||
// The segment direction and inverse squared length are precomputed and cached because
|
||||
// they are reused when projecting pedestrian positions onto the obstacle.
|
||||
//
|
||||
// @param s The first endpoint of the obstacle segment.
|
||||
// @param e The second endpoint of the obstacle segment.
|
||||
//
|
||||
Obstacle(Vector2d s, Vector2d e) : start(s), end(e) {
|
||||
obstacle_v = end - start;
|
||||
float length_sq = obstacle_v.dot(obstacle_v);
|
||||
length_sq_inv = length_sq != 0.0 ? 1.0 / length_sq : 0.0;
|
||||
}
|
||||
|
||||
// Flop count: 5 ADDs, 5 MULTs
|
||||
//
|
||||
// Finds the point on this finite obstacle segment that is closest to p.
|
||||
//
|
||||
// The method projects the vector (p - start) onto the obstacle direction
|
||||
// vector, then clamps the projection factor to [0, 1] so that the returned
|
||||
// point lies on the finite segment.
|
||||
//
|
||||
// Note : If the obstacle is a single point, meaning start == end, length_sq_inv is zero
|
||||
// and the method returns start.
|
||||
//
|
||||
// @param p The point for which the closest obstacle point is computed.
|
||||
// @return The closest point on the obstacle segment to p.
|
||||
//
|
||||
Vector2d find_nearest_obstacle_point(const Vector2d &p) const {
|
||||
|
||||
// # 3 ADDs, 3 MULTs
|
||||
float projection = (p - start).dot(obstacle_v) * length_sq_inv;
|
||||
|
||||
if (projection < 0.0)
|
||||
projection = 0.0;
|
||||
else if (projection > 1.0)
|
||||
projection = 1.0;
|
||||
|
||||
// # 2 ADDs, 2 MULTs
|
||||
return start + obstacle_v * projection;
|
||||
}
|
||||
};
|
||||
|
||||
struct Board {
|
||||
float length; // Board length.
|
||||
float width; // Board width.
|
||||
Obstacle *obstacles; // Array of obstacles contained in the board.
|
||||
int n_obstacles; // Total number of obstacles
|
||||
|
||||
// Constructs a rectangular board of size length x width.
|
||||
//
|
||||
// The input array o contains n user-defined obstacles. The constructor copies
|
||||
// those obstacles and then appends the two horizontal borders of the board (bottom and top) as additional
|
||||
// obstacle segments:
|
||||
//
|
||||
// bottom: (0, 0) -> (length, 0)
|
||||
// top: (0, width) -> (length, width)
|
||||
//
|
||||
// Note: only the horizontal borders are modeled as obstacles. The vertical
|
||||
// borders are left open so pedestrians can enter and leave the walkway without
|
||||
// being affected by repulsive forces from those borders. This is consistent
|
||||
// with Fig. 2 in the paper, where the horizontal walkway boundaries are
|
||||
// emphasized but the vertical ends are not shown as walls.
|
||||
//
|
||||
// @param l The board length.
|
||||
// @param w The board width.
|
||||
// @param n The number of user-defined obstacles in o.
|
||||
// @param o Array of user-defined obstacles to copy into the board obstacles array.
|
||||
//
|
||||
Board(float l, float w, int n, Obstacle *o) : length(l), width(w), n_obstacles(n + 2) {
|
||||
obstacles = new Obstacle[n + 2];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
obstacles[i] = o[i];
|
||||
}
|
||||
|
||||
// Board borders: bottom, top.
|
||||
obstacles[n] = Obstacle(Vector2d(0, 0), Vector2d(l, 0));
|
||||
obstacles[n + 1] = Obstacle(Vector2d(0, w), Vector2d(l, w));
|
||||
}
|
||||
|
||||
// Releases the dynamically allocated obstacle array.
|
||||
~Board() { delete[] obstacles; }
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// # Replaced Vector2d with double
|
||||
// # Predecessor: board.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Obstacle {
|
||||
double start_x;
|
||||
double start_y;
|
||||
double end_x;
|
||||
double end_y;
|
||||
double obstacle_v_x;
|
||||
double obstacle_v_y;
|
||||
double length_sq_inv;
|
||||
|
||||
Obstacle() : start_x(0), start_y(0), end_x(0), end_y(0), obstacle_v_x(0), obstacle_v_y(0), length_sq_inv(0.0) {}
|
||||
|
||||
Obstacle(double s_x, double s_y, double e_x, double e_y) : start_x(s_x), start_y(s_y), end_x(e_x), end_y(e_y) {
|
||||
obstacle_v_x = end_x - start_x;
|
||||
obstacle_v_y = end_y - start_y;
|
||||
|
||||
double length_sq = obstacle_v_x * obstacle_v_x + obstacle_v_y * obstacle_v_y;
|
||||
length_sq_inv = length_sq != 0.0 ? 1.0 / length_sq : 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Board {
|
||||
double length;
|
||||
double width;
|
||||
Obstacle *obstacles;
|
||||
int n_obstacles;
|
||||
|
||||
Board(double l, double w, int n, Obstacle *o) : length(l), width(w), n_obstacles(n + 2) {
|
||||
obstacles = new Obstacle[n + 2];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
obstacles[i] = o[i];
|
||||
}
|
||||
|
||||
obstacles[n] = Obstacle(0, 0, l, 0);
|
||||
obstacles[n + 1] = Obstacle(0, w, l, w);
|
||||
}
|
||||
|
||||
~Board() { delete[] obstacles; }
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// # Replaced double with float
|
||||
// # Predecessor: board_reduced.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Obstacle {
|
||||
float start_x;
|
||||
float start_y;
|
||||
float end_x;
|
||||
float end_y;
|
||||
float obstacle_v_x;
|
||||
float obstacle_v_y;
|
||||
float length_sq_inv;
|
||||
|
||||
Obstacle() : start_x(0), start_y(0), end_x(0), end_y(0), obstacle_v_x(0), obstacle_v_y(0), length_sq_inv(0.0) {}
|
||||
|
||||
Obstacle(float s_x, float s_y, float e_x, float e_y) : start_x(s_x), start_y(s_y), end_x(e_x), end_y(e_y) {
|
||||
obstacle_v_x = end_x - start_x;
|
||||
obstacle_v_y = end_y - start_y;
|
||||
|
||||
float length_sq = obstacle_v_x * obstacle_v_x + obstacle_v_y * obstacle_v_y;
|
||||
length_sq_inv = length_sq != 0.0 ? 1.0 / length_sq : 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Board {
|
||||
float length;
|
||||
float width;
|
||||
Obstacle *obstacles;
|
||||
int n_obstacles;
|
||||
|
||||
Board(float l, float w, int n, Obstacle *o) : length(l), width(w), n_obstacles(n + 2) {
|
||||
obstacles = new Obstacle[n + 2];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
obstacles[i] = o[i];
|
||||
}
|
||||
|
||||
obstacles[n] = Obstacle(0, 0, l, 0);
|
||||
obstacles[n + 1] = Obstacle(0, w, l, w);
|
||||
}
|
||||
|
||||
~Board() { delete[] obstacles; }
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include <new>
|
||||
|
||||
//
|
||||
// $\frac{1}{\tau_{\alpha}}$; $\tau_{\alpha} = 0.5s$
|
||||
//
|
||||
const float tau_alpha_inv = 2.0;
|
||||
|
||||
// $V^0_{\alpha \beta}$
|
||||
const float V0_AB = 2.1;
|
||||
|
||||
// $\sigma$
|
||||
const float SIGMA = 0.3;
|
||||
|
||||
//
|
||||
// $\frac{-1}{2\sigma}$
|
||||
//
|
||||
const float NEG_TWO_SIGMA_INV = -1.0 / (2 * SIGMA);
|
||||
|
||||
//
|
||||
// $\frac{-V^0_{\alpha\beta}}{2\sigma}$
|
||||
//
|
||||
const float NEG_V0_AB_div_TWO_SIGMA = V0_AB * NEG_TWO_SIGMA_INV;
|
||||
|
||||
// $U^0_{\alpha B}$
|
||||
const float U0_AB = 10.0;
|
||||
|
||||
// $R$
|
||||
const float R = 0.2;
|
||||
|
||||
//
|
||||
// $\frac{-1}{R}$
|
||||
//
|
||||
const float NEG_R_INV = -1.0 / R;
|
||||
|
||||
//
|
||||
// $\frac{-U^0_{\alpha B}}{R}$
|
||||
//
|
||||
const float NEG_U0_AB_div_R = -U0_AB / R;
|
||||
|
||||
// $-c$
|
||||
const float c_neg = -0.5;
|
||||
|
||||
// $\varphi$
|
||||
const float phi = 100.0 / 180.0 * M_PI;
|
||||
|
||||
// $cos(\varphi)$
|
||||
const float cos_phi = cos(phi);
|
||||
|
||||
//
|
||||
// $\frac{1}{cos(\varphi)}$
|
||||
//
|
||||
const float cos_phi_inv = 1 / cos(phi);
|
||||
|
||||
// $<v^0>$
|
||||
const float v0_mean = 1.34;
|
||||
|
||||
// $\sqrt{\theta}$
|
||||
const float v0_std_dev = 0.26;
|
||||
|
||||
// $\varDelta_{t}$
|
||||
const float delta_t = 2;
|
||||
|
||||
// $\varDelta_{t}^2$
|
||||
const float delta_t_sq = delta_t * delta_t;
|
||||
|
||||
// $dt$
|
||||
const float dt = 0.02;
|
||||
|
||||
// $-dt$
|
||||
const float dt_neg = -dt;
|
||||
|
||||
// $-c \cdot dt$
|
||||
const float c_neg_times_dt = c_neg * dt;
|
||||
|
||||
//
|
||||
// $\frac{1}{\tau_{\alpha}} \cdot dt$
|
||||
//
|
||||
const float dt_times_tau_alpha_inv = dt * tau_alpha_inv;
|
||||
|
||||
const float cost_add = 1;
|
||||
const float cost_mult = 1;
|
||||
const float cost_div = 1;
|
||||
|
||||
// https://acl.inf.ethz.ch/teaching/fastcode/knowledgebase/#:~:text=How%20do%20exp(x)%2C%20sin(x)%2C%20etc.%20count%20in%20the%20flopcount%20of%20an%20algorithm%3F
|
||||
const float cost_exp = 30;
|
||||
|
||||
// -O3 maps each sqrt() call to an instruction
|
||||
const float cost_sqrt = 1;
|
||||
|
||||
// Numerical tolerance used to avoid division by zero and unstable operations
|
||||
// when distances or norms are extremely small.
|
||||
const float EPS = 1e-9;
|
||||
|
||||
// Squared numerical tolerance
|
||||
const float EPS_SQ = EPS * EPS;
|
||||
|
||||
// Cutoff for pedestrian-pedestrian repulsion
|
||||
const float CUTOFF = 12.0;
|
||||
const float CUTOFF_SQ = CUTOFF * CUTOFF;
|
||||
|
||||
const float cos_phi_sq = cos_phi * cos_phi;
|
||||
|
||||
const size_t CACHE_BLOCK_SIZE = std::hardware_destructive_interference_size;
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include "constants_float.hpp"
|
||||
#include "vector2d_float.hpp"
|
||||
|
||||
// Needed for visual simulation, in order to distinguish two groups of pedestrians:
|
||||
// - White pedestrians move from left to right
|
||||
// - Black pedestrians move from right to left
|
||||
enum Color { WHITE, BLACK};
|
||||
|
||||
struct Pedestrian {
|
||||
|
||||
Color color;
|
||||
|
||||
// $\vec{v}_{\alpha}(t)$
|
||||
Vector2d curr_vel; // v_alpha (actual, ≤ v_max)
|
||||
|
||||
// $\vec{w}_{\alpha}$
|
||||
Vector2d w; // w_alpha (preferred, integrates force)
|
||||
|
||||
// $\vec{r}_\alpha(t)$
|
||||
Vector2d curr_pos;
|
||||
|
||||
// $\vec{e}_{\alpha}(t)$
|
||||
Vector2d e; // desired direction vector
|
||||
|
||||
// $v_{\alpha}^{max} = 1.3 v^{0}_{\alpha}$
|
||||
float v_max;
|
||||
|
||||
// $v_\alpha^0$
|
||||
float desired_v0;
|
||||
|
||||
// $\vec{r}^0_\alpha$
|
||||
Vector2d destination;
|
||||
// $s_\beta^2 = (v_\beta \Delta t)^2$
|
||||
float s_b_sq;
|
||||
// $s_\beta \vec{e}_\beta$
|
||||
Vector2d s_b_e;
|
||||
|
||||
// Default constructor: initializes a pedestrian with color WHITE and all vector/scalar fields set to zero.
|
||||
Pedestrian() : color(WHITE), curr_vel(0.0, 0.0), w(0.0, 0.0), curr_pos(0.0, 0.0), e(0.0, 0.0), v_max(0.0), desired_v0(0.0), destination(0.0, 0.0), s_b_sq(0.0), s_b_e(0.0, 0.0) {}
|
||||
|
||||
// Constructs a pedestrian with the given initial state and precomputes the
|
||||
// quantities used in the pedestrian-pedestrian repulsion term.
|
||||
//
|
||||
// The preferred velocity w is initialized to the current velocity c_v. The
|
||||
// cached quantities s_b_sq and s_b_e correspond to the predicted step of this
|
||||
// pedestrian over $\Delta t$:
|
||||
//
|
||||
// s_b = ||c_v|| * dt
|
||||
// s_b_sq = s_b^2
|
||||
// s_b_e = e * s_b
|
||||
//
|
||||
// These values are used when another pedestrian computes the elliptical
|
||||
// interaction term involving this pedestrian.
|
||||
//
|
||||
// @param clr The display/color category of the pedestrian.
|
||||
// @param c_v The initial current velocity.
|
||||
// @param c_p The initial current position.
|
||||
// @param e The initial desired direction of motion.
|
||||
// @param v_max The maximum speed that the pedestrian can reach.
|
||||
// @param desired_v0 The desired walking speed.
|
||||
// @param d The pedestrian's target destination point.
|
||||
//
|
||||
Pedestrian(Color clr, Vector2d c_v, Vector2d c_p, Vector2d e, float v_max, float desired_v0, Vector2d d) : color(clr), curr_vel(c_v), w(c_v), curr_pos(c_p), e(e), v_max(v_max), desired_v0(desired_v0), destination(d), s_b_sq(c_v.dot(c_v) * delta_t_sq), s_b_e(e * c_v.norm() * delta_t) {}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
// # Replaced double with float
|
||||
// # Predecessor: pedestrian_reduced.hpp
|
||||
|
||||
#pragma once
|
||||
#include "constants_float.hpp"
|
||||
|
||||
struct Pedestrian {
|
||||
|
||||
int color;
|
||||
|
||||
float curr_vel_x;
|
||||
float curr_vel_y;
|
||||
|
||||
float w_x;
|
||||
float w_y;
|
||||
|
||||
float curr_pos_x;
|
||||
float curr_pos_y;
|
||||
|
||||
float e_x;
|
||||
float e_y;
|
||||
|
||||
float v_max;
|
||||
|
||||
float desired_v0;
|
||||
|
||||
float destination_x;
|
||||
float destination_y;
|
||||
|
||||
float s_b_sq;
|
||||
float s_b_e_x;
|
||||
float s_b_e_y;
|
||||
|
||||
Pedestrian() : color(0), curr_vel_x(0.0), curr_vel_y(0), w_x(0.0), w_y(0.0), curr_pos_x(0.0), curr_pos_y(0.0), e_x(0.0), e_y(0.0), v_max(0.0), desired_v0(0.0), destination_x(0.0), destination_y(0.0), s_b_sq(0.0), s_b_e_x(0.0), s_b_e_y(0.0) {}
|
||||
|
||||
Pedestrian(int clr, float c_v_x, float c_v_y, float c_p_x, float c_p_y, float e_x, float e_y, float v_max, float desired_v0, float d_x, float d_y)
|
||||
: color(clr), curr_vel_x(c_v_x), curr_vel_y(c_v_y), w_x(c_v_x), w_y(c_v_y), curr_pos_x(c_p_x), curr_pos_y(c_p_y), e_x(e_x), e_y(e_y), v_max(v_max), desired_v0(desired_v0), destination_x(d_x), destination_y(d_y), s_b_sq((c_v_x * c_v_x + c_v_y * c_v_y) * delta_t_sq), s_b_e_x(e_x * (sqrt(c_v_x * c_v_x + c_v_y * c_v_y)) * delta_t), s_b_e_y(e_y * (sqrt(c_v_x * c_v_x + c_v_y * c_v_y)) * delta_t) {}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "board_float.hpp"
|
||||
#include "pedestrian_float.hpp"
|
||||
|
||||
// Initializes the pedestrians used in the simulation.
|
||||
//
|
||||
// The returned array contains n_p pedestrians split into two groups:
|
||||
// one group walking from left to right and one group walking from right to left.
|
||||
// Pedestrian positions, desired speeds, destinations, and initial directions are
|
||||
// initialized according to the simulation setup.
|
||||
//
|
||||
// @param n_p : Number of pedestrians to initialize.
|
||||
// @return Pointer to a dynamically allocated array of pedestrians.
|
||||
Pedestrian *init_pedestrians(int n_p);
|
||||
|
||||
// Initializes a simulation board with no obstacles inside.
|
||||
//
|
||||
// @return Initialized Board instance.
|
||||
Board init_board_without_obstacles();
|
||||
|
||||
// Runs the social force model with n_p pedestrians for n_iter iterations,
|
||||
// i.e., n_iter * dt simulated seconds.
|
||||
// If dump_path is not nullptr, the simulation states are written to that CSV
|
||||
// file, which can be used to generate a visualization video. If dump_path is
|
||||
// nullptr, no output file is generated.
|
||||
//
|
||||
// @param pedestrians : Array of pedestrians to simulate. The array is updated in place.
|
||||
// @param board : Board containing the simulation dimensions and obstacles.
|
||||
// @param n_p : Number of pedestrians.
|
||||
// @param n_iter : Number of simulation iterations.
|
||||
// @param dump_path : Optional path to the CSV output file.
|
||||
// @return 0 on success.
|
||||
int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path);
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
struct Vector2d {
|
||||
float x, y;
|
||||
Vector2d(float a, float b) : x(a), y(b) {}
|
||||
Vector2d() : x(.0), y(.0) {}
|
||||
Vector2d operator+(Vector2d v) const { return Vector2d(v.x + x, v.y + y); }
|
||||
Vector2d operator-(Vector2d v) const { return Vector2d(x - v.x, y - v.y); }
|
||||
Vector2d operator-(float a) const { return Vector2d(x - a, y - a); }
|
||||
Vector2d operator+(float a) const { return Vector2d(x + a, y + a); }
|
||||
Vector2d operator/(float a) const { return Vector2d(x / a, y / a); }
|
||||
Vector2d operator*(float a) const { return Vector2d(x * a, y * a); }
|
||||
Vector2d operator+=(const Vector2d &v) {
|
||||
*this = *this + v;
|
||||
return *this;
|
||||
}
|
||||
Vector2d operator-=(const Vector2d &v) {
|
||||
*this = *this - v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2d reverse_sign() { return Vector2d(-x, -y); }
|
||||
|
||||
// # 1 ADD, 2 MULTs, 1 SQRT
|
||||
float norm() { return sqrt(x * x + y * y); }
|
||||
|
||||
// # 1 ADD, 2 MULTs
|
||||
float dot(Vector2d v) { return x * v.x + y * v.y; }
|
||||
void reset() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user