Ultra 0.9.4
Loading...
Searching...
No Matches
oracle.h
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_ORACLE_H)
14#define ULTRA_ORACLE_H
15
16#include "kernel/exceptions.h"
19#include "kernel/gp/team.h"
20
21#include <numbers>
22
23namespace ultra::src
24{
25
27
28// Forward declarations.
29class basic_oracle;
30
31namespace serialize
32{
34namespace oracle
35{
36
37template<Individual P = gp::individual>
38[[nodiscard]] std::unique_ptr<basic_oracle>
39load(std::istream &, const symbol_set &);
40
41} // namespace oracle
42
43bool save(std::ostream &, const basic_oracle *);
44bool save(std::ostream &, const basic_oracle &);
45bool save(std::ostream &, const std::unique_ptr<basic_oracle> &);
47} // namespace serialize
48
54
60/// `basic_oracle` always calculates a meaningful value for the end-user (the
61/// class of an example, an approximation...) while `src::interpreter` often
62/// outputs an intermediate value that is just a building block for
63/// `basic_oracle` (e.g. classification tasks with discriminant functions).
64/// The typical use chain is:
65/// src::evaluator --[uses]--> basic_oracle --[uses]--> interpreter.
66///
67/// \note
68/// Another interesting function of `basic_oracle` is that it extends the
69/// functionalities of interpreter to teams.
70///
72{
73public:
74 virtual ~basic_oracle() = default;
75
76 [[nodiscard]] virtual value_t operator()(
77 const std::vector<value_t> &) const = 0;
78
79 [[nodiscard]] virtual bool is_valid() const = 0;
80
81 [[nodiscard]] virtual std::string name(const value_t &) const = 0;
82 [[nodiscard]] virtual classification_result tag(
83 const std::vector<value_t> &) const = 0;
84
85private:
86 // ---- Serialization ----
87 [[nodiscard]] virtual std::string serialize_id() const = 0;
88 virtual bool save(std::ostream &) const = 0;
89
90 template<Individual P> friend std::unique_ptr<basic_oracle>
91 serialize::oracle::load(std::istream &, const symbol_set &);
92 friend bool serialize::save(std::ostream &, const basic_oracle &);
93};
94
95// ***********************************************************************
96// * Symbolic regression *
97// ***********************************************************************
98
104/// everything it needs inside (it will survive the death of the
105/// individual it's constructed on). Sometimes we prefer space
106/// efficiency (typically inside an evaluator)
107///
108template<Individual P, bool S>
110 protected internal::reg_oracle_storage<P, S>
111{
112public:
113 explicit basic_reg_oracle(const P &);
114 basic_reg_oracle(std::istream &, const symbol_set &);
115
116 [[nodiscard]] value_t operator()(const std::vector<value_t> &) const final;
117
118 [[nodiscard]] std::string name(const value_t &) const final;
119
120 [[nodiscard]] bool is_valid() const final;
121
122 // ---- Serialization ----
123 static const std::string SERIALIZE_ID;
124 bool save(std::ostream &) const final;
126private:
127 // Not useful for regression tasks and moved to private section.
128 [[noreturn]] classification_result tag(
129 const std::vector<value_t> &) const final;
130
131 [[nodiscard]] std::string serialize_id() const noexcept final
132 { return SERIALIZE_ID; }
133};
134
138/// \tparam O predictor type
139///
140/// This adaptor allows any user-defined regression predictor to be used as a
141/// `basic_oracle`. The wrapped predictor must satisfy `RegressionPredictor`,
142/// i.e. be callable with an input example and return a `value_t`.
143///
144/// \note
145/// Calling `tag()` on this adaptor is invalid and results in an exception.
146///
147/// \note
148/// The adaptor is intentionally non-serializable.
149///
150template<RegressionPredictor O>
153public:
154 explicit reg_oracle_adaptor(O);
155
156 [[nodiscard]] value_t operator()(const std::vector<value_t> &) const override;
157
160 [[nodiscard]] bool is_valid() const override { return true; }
161
162 [[nodiscard]] std::string name(const value_t &v) const override;
163
164private:
165 [[noreturn]] classification_result tag(
166 const std::vector<value_t> &) const override;
167 [[nodiscard]] std::string serialize_id() const override;
168 bool save(std::ostream &) const override;
169
170 O oracle_;
171};
172
173// ***********************************************************************
174// * Classification *
175// ***********************************************************************
176
187{
188 mv, // majority voting
189 wta, // winner takes all
190
191 standard = wta
192};
193
204{
205public:
206 [[nodiscard]] value_t operator()(const std::vector<value_t> &) const final;
207
208 [[nodiscard]] std::string name(const value_t &) const final;
209
210protected:
211 explicit basic_class_oracle(std::vector<std::string> = {});
212
213 [[nodiscard]] static std::vector<std::string> class_names(const dataframe &);
214
215 bool load_names(std::istream &);
216 bool save_names(std::ostream &) const;
217
218private:
219 std::vector<std::string> names_ {};
220};
221
231template<class I, bool S>
233{
234public:
236 std::vector<std::string> = {});
237 basic_gaussian_oracle(std::istream &, const symbol_set &);
238
240 const std::vector<value_t> &) const final;
241
242 [[nodiscard]] bool is_valid() const final;
243
244 // ---- Serialization ----
245 static const std::string SERIALIZE_ID;
246 bool save(std::ostream &) const final;
247
248private:
249 // ---- Private support methods ----
250 void fill_vector(const dataframe &);
251
252 [[nodiscard]] std::string serialize_id() const noexcept final
253 { return SERIALIZE_ID; }
254
255 // ---- Private data members ----
257
258 // `gauss_dist[i]` contains the gaussian distribution of the i-th class of
259 // the classification problem.
260 std::vector<distribution<double>> gauss_dist_ {};
261};
262
272template<class I, bool S>
274{
275public:
276 basic_binary_oracle(const I &, const dataframe &,
277 std::vector<std::string> = {});
278 basic_binary_oracle(std::istream &, const symbol_set &);
279
281 const std::vector<value_t> &) const final;
282
283 [[nodiscard]] bool is_valid() const final;
284
285 // ---- Serialization ----
286 static const std::string SERIALIZE_ID;
287 bool save(std::ostream &) const final;
288
289private:
290 [[nodiscard]] std::string serialize_id() const noexcept final
291 { return SERIALIZE_ID; }
292
294};
295
311template<ClassificationPredictor O>
313{
314public:
315 explicit class_oracle_adaptor(O, std::vector<std::string> = {});
316
319 [[nodiscard]] bool is_valid() const override { return true; }
320
321 [[nodiscard]] classification_result tag(
322 const std::vector<value_t> &) const override;
323
324private:
325 [[nodiscard]] std::string serialize_id() const override;
326 bool save(std::ostream &) const override;
327
328 O oracle_;
329};
330
331// ***********************************************************************
332// * Extensions to support teams *
333// ***********************************************************************
334
341template<ClassificationPredictor O,
342 team_composition C = team_composition::standard>
344{
345public:
346 template<Individual I>
347 team_class_oracle(const gp::team<I> &, const dataframe &,
348 std::vector<std::string> = {});
349 team_class_oracle(std::istream &, const symbol_set &);
350
352 const std::vector<value_t> &) const final;
353
354 [[nodiscard]] bool is_valid() const final;
355
356 static const std::string SERIALIZE_ID;
357
358private:
359 bool save(std::ostream &) const final;
360 [[nodiscard]] std::string serialize_id() const noexcept final;
361
362 // The components of the team never store the names of the classes. If we
363 // need the names, the master class will memorize them.
364 std::vector<O> team_;
365
366 src::class_t classes_ {};
367};
368
375template<class I, bool S>
376class basic_gaussian_oracle<gp::team<I>, S>
377 : public team_class_oracle<basic_gaussian_oracle<I, S>>
378{
379public:
380 using basic_gaussian_oracle::team_class_oracle::team_class_oracle;
381};
382
389template<class I, bool S>
390class basic_binary_oracle<gp::team<I>, S>
391 : public team_class_oracle<basic_binary_oracle<I, S>>
392{
393public:
394 using basic_binary_oracle::team_class_oracle::team_class_oracle;
395};
396
397// ***********************************************************************
398// * Template aliases to simplify the syntax and help the user *
399// ***********************************************************************
400template<Individual P>
401class reg_oracle : public basic_reg_oracle<P, true>
402{
403public:
404 using reg_oracle::basic_reg_oracle::basic_reg_oracle;
405};
406template<Individual P> reg_oracle(const P &) -> reg_oracle<P>;
407
408template<Individual P>
409class gaussian_oracle : public basic_gaussian_oracle<P, true>
410{
411public:
412 gaussian_oracle(const P &ind, const dataframe &d)
414 {}
415
416 gaussian_oracle(std::istream &in, const symbol_set &ss)
418 {}
419};
420template<Individual P> gaussian_oracle(const P &, const dataframe &)
422
423template<Individual P>
424class binary_oracle : public basic_binary_oracle<P, true>
425{
426public:
427 binary_oracle(const P &ind, const dataframe &d)
429 {}
430
431 binary_oracle(std::istream &in, const symbol_set &ss)
433 {}
434};
435template<class P> binary_oracle(const P &, const dataframe &)
437
439
440} // namespace ultra::src
441
442#endif // include guard
std::size_t class_t
The type used as class ID in classification tasks.
Definition classification_result.h:22
Definition team.h:72
basic_binary_oracle(const I &, const dataframe &, std::vector< std::string >={})
Definition oracle.h:558
bool save(std::ostream &) const final
Definition oracle.h:623
classification_result tag(const std::vector< value_t > &) const final
Definition oracle.h:597
bool is_valid() const final
Definition oracle.h:611
std::string name(const value_t &) const final
Returns the class name, falling back to a numeric name for unknown IDs.
Definition oracle.cc:35
value_t operator()(const std::vector< value_t > &) const final
Returns the predicted class label.
Definition oracle.cc:29
basic_class_oracle(std::vector< std::string >={})
Definition oracle.cc:23
bool load_names(std::istream &)
Loads the class names, accepting a zero count for omitted names.
Definition oracle.cc:57
static std::vector< std::string > class_names(const dataframe &)
Collects the class names from the training set.
Definition oracle.cc:45
bool save_names(std::ostream &) const
Saves a count followed by one class name per line.
Definition oracle.cc:75
bool save(std::ostream &) const final
Definition oracle.h:520
basic_gaussian_oracle(const I &, const dataframe &, std::vector< std::string >={})
Definition oracle.h:219
classification_result tag(const std::vector< value_t > &) const final
Definition oracle.h:438
bool is_valid() const final
Definition oracle.h:539
Definition oracle.h:72
Definition oracle.h:111
basic_reg_oracle(const P &)
Definition oracle.h:33
value_t operator()(const std::vector< value_t > &) const final
Definition oracle.h:60
bool save(std::ostream &) const final
Definition oracle.h:125
std::string name(const value_t &) const final
Definition oracle.h:104
bool is_valid() const final
Definition oracle.h:113
Definition oracle.h:425
bool is_valid() const override
Definition oracle.h:319
class_oracle_adaptor(O, std::vector< std::string >={})
Definition oracle.h:640
classification_result tag(const std::vector< value_t > &) const override
Definition oracle.h:655
Definition dataframe.h:76
Definition oracle.h:410
reg_oracle_adaptor(O)
Definition oracle.h:138
bool is_valid() const override
Definition oracle.h:160
std::string name(const value_t &v) const override
Definition oracle.h:164
value_t operator()(const std::vector< value_t > &) const override
Definition oracle.h:152
Definition oracle.h:402
team_class_oracle(const gp::team< I > &, const dataframe &, std::vector< std::string >={})
Definition oracle.h:700
bool is_valid() const final
Definition oracle.h:824
classification_result tag(const std::vector< value_t > &) const final
Definition oracle.h:752
team_class_oracle(const gp::team< I > &t, const dataframe &d, std::vector< std::string > names)
Definition oracle.tcc:699
Definition symbol_set.h:115
STL namespace.
bool save(std::ostream &out, F f)
Definition fitness.h:151
std::variant< D_VOID, D_INT, D_DOUBLE, D_STRING, const D_NULLARY *, D_ADDRESS, const D_VARIABLE *, D_IVECTOR > value_t
Definition value.h:54
bool save(std::ostream &out, const basic_oracle &ora)
Definition oracle.cc:99
team_composition
Definition oracle.h:187
Definition classification_result.h:28