Ultra 0.9.4
Loading...
Searching...
No Matches
fitness.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_FITNESS_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_FITNESS_TCC)
18#define ULTRA_FITNESS_TCC
19
23inline constexpr fitnd::fitnd(std::initializer_list<double> l) : vect_(l)
24{
25}
26
27template<Fitness F>
28[[nodiscard]] constexpr F lowest() noexcept
29{
30 return std::numeric_limits<F>::lowest();
31}
32
33template<std::integral F>
34[[nodiscard]] bool isfinite(F) noexcept
35{
36 return true;
37}
38
39template<std::floating_point F>
40[[nodiscard]] bool isfinite(F f)
41{
42 return std::isfinite(f);
43}
44
49template<MultiDimFitness F>
50[[nodiscard]] bool isfinite(const F &f)
51{
52 return std::ranges::all_of(f, [](auto v) { return isfinite(v); });
53}
54
72template<Fitness F>
73requires std::is_arithmetic_v<F>
74[[nodiscard]] bool dominating(const F &lhs, const F &rhs)
75{
76 return rhs < lhs;
77}
78
79template<MultiDimFitness F>
80[[nodiscard]] bool dominating(const F &lhs, const F &rhs)
81{
82 Expects(std::ranges::size(lhs) == std::ranges::size(rhs));
83
84 bool one_better(false);
85
86 for (auto [l, r] : std::views::zip(lhs, rhs))
87 if (l > r)
88 one_better = true;
89 else if (l < r)
90 return false;
91
92 return one_better;
93}
94
95template<MultiDimFitness F>
96[[nodiscard]] bool almost_equal(const F &lhs, const F &rhs)
97{
98 return std::ranges::equal(
99 lhs, rhs,
100 [](auto v1, auto v2) { return almost_equal(v1, v2); });
101}
102
115template<Fitness F>
116requires std::is_arithmetic_v<F>
117[[nodiscard]] double distance(F f1, F f2)
118{
119 if constexpr (std::floating_point<F>)
120 return std::fabs(f1 - f2);
121 else
122 {
123 // Compute the absolute difference in the corresponding unsigned type.
124 // This avoids signed overflow, including the lowest()/max() case.
125 // Conversion from signed to unsigned is well-defined modulo 2^N and the
126 // subtraction is then performed in the unsigned domain.
127 using U = std::make_unsigned_t<F>;
128
129 return static_cast<double>(f1 >= f2 ? U(f1) - U(f2) : U(f2) - U(f1));
130 }
131}
132
133template<MultiDimFitness F>
134[[nodiscard]] double distance(const F &f1, const F &f2)
135{
136 Expects(std::ranges::size(f1) == std::ranges::size(f2));
137
138 return std::transform_reduce(
139 std::ranges::begin(f1), std::ranges::end(f1), std::ranges::begin(f2), 0.0,
140 std::plus{}, [](auto a, auto b) { return ultra::distance(a, b); });
141}
142
148template<Fitness F>
149requires std::floating_point<F>
150[[nodiscard]] bool save(std::ostream &out, F f)
151{
152 save_float_to_stream(out, f);
153 out << '\n';
154
155 return out.good();
156}
157
158template<std::integral F>
159[[nodiscard]] bool save(std::ostream &out, F f)
160{
161 out << f << '\n';
162
163 return out.good();
164}
165
166template<MultiDimFitness F>
167requires std::floating_point<std::ranges::range_value_t<F>>
168[[nodiscard]] bool save(std::ostream &out, const F &f)
169{
170 out << std::ranges::size(f);
171
172 for (auto v : f)
173 {
174 out << ' ';
175 save_float_to_stream(out, v);
176 }
177
178 return out.good();
179}
180
189template<std::floating_point F>
190bool load(std::istream &in, F *f)
191{
192 return load_float_from_stream(in, f);
193}
194
195template<std::integral F>
196bool load(std::istream &in, F *f)
197{
198 return in >> *f;
199}
200
201#endif // include guard
bool dominating(const F &lhs, const F &rhs)
Definition fitness.tcc:74
double distance(F f1, F f2)
Definition fitness.tcc:117
bool load(std::istream &in, F *f)
Definition fitness.tcc:190
bool save(std::ostream &out, F f)
Definition fitness.tcc:150
double distance(F f1, F f2)
Definition fitness.h:118