Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
utils.hh
Go to the documentation of this file.
1#ifndef UTOPIA_MODELS_SIMPLEFLOCKING_UTILS_HH
2#define UTOPIA_MODELS_SIMPLEFLOCKING_UTILS_HH
3
4#include <cmath>
5#include <random>
6#include <numeric>
7#include <vector>
8#include <limits>
9
10#include <armadillo>
11#include <spdlog/spdlog.h>
12
13#include <utopia/core/types.hh>
14
15
17
18constexpr double TAU = 2*M_PI;
19constexpr double NaN = std::numeric_limits<double>::quiet_NaN();
20
21
22// -- Angle-related tools -----------------------------------------------------
23
25template<class RNG, class T=double>
26T random_angle (const std::shared_ptr<RNG>& rng) {
27 return std::uniform_real_distribution<T>(-M_PI, +M_PI)(*rng);
28}
29
31template<class T>
33 angle = std::fmod(angle + M_PI, TAU);
34 while (angle < 0.) {
35 angle += TAU;
36 }
37 return angle - M_PI;
38}
39
41template<class Container>
44 angles.begin(), angles.end(), angles.begin(),
45 [](auto angle){ return constrain_angle(angle); }
46 );
47}
48
49
50// -- Geometry ----------------------------------------------------------------
51
53
57template<class Container>
59 if (velocities.empty()) {
60 return std::numeric_limits<double>::quiet_NaN();
61 }
62
63 using Vec = typename Container::value_type;
64 Vec zero = velocities[0];
65 zero.fill(0.);
66
67 const Vec group_velocity = std::accumulate(
68 velocities.begin(), velocities.end(), zero
69 );
70 return arma::norm(group_velocity, 2) / velocities.size();
71}
72
73
74// -- Circular Statistics -----------------------------------------------------
75
77template<class Container>
79 static_assert(
80 std::is_floating_point<typename Container::value_type>::value,
81 "need angles specified as floating-point types!"
82 );
83
84 const auto sin_sum = std::accumulate(
85 angles.begin(), angles.end(), 0.,
86 [](auto a1, auto a2){ return a1 + std::sin(a2); }
87 );
88 const auto cos_sum = std::accumulate(
89 angles.begin(), angles.end(), 0.,
90 [](auto a1, auto a2){ return a1 + std::cos(a2); }
91 );
92
93 return std::make_pair(sin_sum, cos_sum);
94}
95
96
98
107template<class Container = std::vector<double>>
109 if (angles.empty()) {
110 return std::numeric_limits<double>::quiet_NaN();
111 }
112
113 const auto&& [sin_sum, cos_sum] = _circular_sin_cos_sum(angles);
114 return constrain_angle(std::atan2(sin_sum, cos_sum));
115}
116
117
119
128template<class Container = std::vector<double>>
130 if (angles.empty()) {
131 return std::make_pair(NaN, NaN);
132 }
133
134 const auto&& [sin_sum, cos_sum] = _circular_sin_cos_sum(angles);
135 const auto mean = constrain_angle(std::atan2(sin_sum, cos_sum));
136
137 const auto r = std::min(
138 1., std::sqrt(sin_sum*sin_sum + cos_sum*cos_sum) / angles.size()
139 );
140 const auto std = std::sqrt(-2. * std::log(r));
141
142 return std::make_pair(mean, std);
143}
144
145
146} // namespace Utopia::Models::SimpleFlocking
147
148#endif // UTOPIA_MODELS_SIMPLEFLOCKING_UTILS_HH
OutputIt transform(const Utopia::ExecPolicy policy, InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op)
Apply a unary operator to a range and store the result in a new range.
Definition parallel.hh:368
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
Definition SimpleFlocking.hh:15
double absolute_group_velocity(const Container &velocities)
Computes the absolute group velocity from a container of velocity vectors.
Definition utils.hh:58
T random_angle(const std::shared_ptr< RNG > &rng)
Returns a uniformly random angle value in [-π, +π)
Definition utils.hh:26
void constrain_angles(Container &angles)
In-place constrains all angles in a container to interval [-π, +π)
Definition utils.hh:42
auto _circular_sin_cos_sum(const Container &angles)
Compute sum of sine and cosine values from angles in a container.
Definition utils.hh:78
T constrain_angle(T angle)
Constrains an angle value to interval [-π, +π)
Definition utils.hh:32
auto circular_mean_and_std(const Container &angles)
Computes the circular mean and std from a sample of (constrained) angles.
Definition utils.hh:129
constexpr double NaN
Definition utils.hh:19
auto circular_mean(const Container &angles)
Computes the circular mean from a sample of (constrained) angles.
Definition utils.hh:108
constexpr double TAU
Definition utils.hh:18
Definition parallel.hh:235