663 lines
84 KiB
XML
663 lines
84 KiB
XML
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
|
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="__exponential_8h_source" xml:lang="en-US">
|
|
<title>Exponential.h</title>
|
|
<indexterm><primary>Exponential/Exponential.h</primary></indexterm>
|
|
<programlisting linenumbering="unnumbered">1 <emphasis role="preprocessor">#pragma once</emphasis>
|
|
2 <emphasis role="preprocessor">#ifndef JONATHAN_RAMPERSAD_EXPONENTIAL_H_</emphasis>
|
|
3 <emphasis role="preprocessor">#define JONATHAN_RAMPERSAD_EXPONENTIAL_H_</emphasis>
|
|
4
|
|
5 <emphasis role="preprocessor">#include <ostream></emphasis>
|
|
6 <emphasis role="preprocessor">#include <vector></emphasis>
|
|
7 <emphasis role="preprocessor">#include <float.h></emphasis>
|
|
8 <emphasis role="preprocessor">#include <random></emphasis>
|
|
9 <emphasis role="preprocessor">#include <algorithm></emphasis>
|
|
10 <emphasis role="preprocessor">#include <execution></emphasis>
|
|
11 <emphasis role="preprocessor">#include <exception></emphasis>
|
|
12
|
|
13 <emphasis role="keyword">namespace </emphasis>JRAMPERSAD
|
|
14 {
|
|
15     <emphasis role="keyword">namespace </emphasis>EXPONENTIAL
|
|
16     {
|
|
20         <emphasis role="keyword">struct </emphasis><link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>
|
|
21         {
|
|
23             <emphasis role="keywordtype">double</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a316979973a2a6b70b00520c2f753a43c">min_range</link> = -100;
|
|
25             <emphasis role="keywordtype">double</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a9b8f1e5367f6b0d8b16eecaea53b40e2">max_range</link> = 100;
|
|
27             <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a4a67bad303f8a4fca40020a0802524c5">num_of_generations</link> = 10;
|
|
29             <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link> = 1000;
|
|
31             <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a6ec95fe6cc95dc32727659cf5bb1be12">data_size</link> = 100000;
|
|
33             <emphasis role="keywordtype">double</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a736488b3cfeebda7b93b3e8c6f576bf8">mutation_percentage</link> = 0.01;
|
|
34         };
|
|
35
|
|
36         <emphasis role="keyword">namespace </emphasis>detail
|
|
37         {
|
|
38             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
39             [[nodiscard(<emphasis role="stringliteral">"MATH::ABS(T) returns a value of type T"</emphasis>)]] T ABS(<emphasis role="keyword">const</emphasis> T& n) <emphasis role="keyword">noexcept</emphasis>
|
|
40             {
|
|
41                 <emphasis role="keywordflow">return</emphasis> n < 0 ? n * -1 : n;
|
|
42             }
|
|
43
|
|
44             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
45             [[nodiscard(<emphasis role="stringliteral">"MATH::NEGATE(T) returns a value of type T"</emphasis>)]] T NEGATE(<emphasis role="keyword">const</emphasis> T& n) <emphasis role="keyword">noexcept</emphasis>
|
|
46             {
|
|
47                 <emphasis role="keywordflow">return</emphasis> n * -1;
|
|
48             }
|
|
49
|
|
50             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
51             [[nodiscard(<emphasis role="stringliteral">"MATH::POW(T, int) returns a value of type T"</emphasis>)]] T POW(<emphasis role="keyword">const</emphasis> T& n, <emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">int</emphasis>& exp) <emphasis role="keyword">noexcept</emphasis>
|
|
52             {
|
|
53                 <emphasis role="keywordflow">if</emphasis> (exp == 0)
|
|
54                     <emphasis role="keywordflow">return</emphasis> 1;
|
|
55
|
|
56                 T res = n;
|
|
57                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">int</emphasis> i = 1; i < exp; i++)
|
|
58                 {
|
|
59                     res *= n;
|
|
60                 }
|
|
61
|
|
62                 <emphasis role="keywordflow">return</emphasis> res;
|
|
63             }
|
|
64
|
|
65             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
66             [[nodiscard(<emphasis role="stringliteral">"MATH::SUM(std::vector<T>) returns a value of type T"</emphasis>)]] T SUM(<emphasis role="keyword">const</emphasis> std::vector<T>& vec) <emphasis role="keyword">noexcept</emphasis>
|
|
67             {
|
|
68                 T res{};
|
|
69                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : vec)
|
|
70                     res += val;
|
|
71                 <emphasis role="keywordflow">return</emphasis> res;
|
|
72             }
|
|
73
|
|
74             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
75             [[nodiscard]] T MEDIAN(std::vector<T> vec) <emphasis role="keyword">noexcept</emphasis>
|
|
76             {
|
|
77                 std::sort(
|
|
78                     vec.begin(),
|
|
79                     vec.end(),
|
|
80                     [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
81                         return lhs < rhs;
|
|
82                     });
|
|
83
|
|
84                 <emphasis role="keywordflow">return</emphasis> vec[vec.size() / 2];
|
|
85             }
|
|
86
|
|
87             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
88             [[nodiscard]] <emphasis role="keywordtype">double</emphasis> MEAN(<emphasis role="keyword">const</emphasis> std::vector<T>& vec) <emphasis role="keyword">noexcept</emphasis>
|
|
89             {
|
|
90                 <emphasis role="keywordflow">return</emphasis> SUM(vec) / vec.size();
|
|
91             }
|
|
92
|
|
93             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
94             [[noreturn]] <emphasis role="keywordtype">void</emphasis> SortASC(std::vector<T>& vec)
|
|
95             {
|
|
96                 std::sort(
|
|
97                     std::execution::par,
|
|
98                     vec.begin(), vec.end(),
|
|
99                     [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
100                         return lhs < rhs;
|
|
101                     });
|
|
102             }
|
|
103
|
|
104             <emphasis role="keyword">template</emphasis><<emphasis role="keyword">typename</emphasis> T>
|
|
105             [[noreturn]] <emphasis role="keywordtype">void</emphasis> SortDESC(std::vector<T>& vec)
|
|
106             {
|
|
107                 std::sort(
|
|
108                     std::execution::par,
|
|
109                     vec.begin(), vec.end(),
|
|
110                     [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
111                         return lhs > rhs;
|
|
112                     });
|
|
113             }
|
|
114
|
|
115             <emphasis role="comment">// Genetic Algorithm helper struct</emphasis>
|
|
116             <emphasis role="keyword">struct </emphasis>GA_Solution
|
|
117             {
|
|
118                 <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">short</emphasis> lrgst_expo;
|
|
119                 <emphasis role="keywordtype">double</emphasis> rank, x, y_val;
|
|
120
|
|
121                 GA_Solution() : lrgst_expo(0), rank(0), x(0), y_val(0) {}
|
|
122                 GA_Solution(<emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">short</emphasis> Lrgst_expo, <emphasis role="keywordtype">double</emphasis> Rank, <emphasis role="keywordtype">double</emphasis> x_val, <emphasis role="keywordtype">double</emphasis> y = 0) : lrgst_expo(Lrgst_expo), rank(Rank), x(x_val), y_val(y) {}
|
|
123                 <emphasis role="keyword">virtual</emphasis> ~GA_Solution() = <emphasis role="keywordflow">default</emphasis>;
|
|
124
|
|
125                 <emphasis role="keywordtype">void</emphasis> fitness(<emphasis role="keyword">const</emphasis> std::vector<int64_t>& constants)
|
|
126                 {
|
|
127                     <emphasis role="keywordtype">double</emphasis> ans = 0;
|
|
128                     <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">int</emphasis> i = lrgst_expo; i >= 0; i--)
|
|
129                         ans += constants[i] * POW(x, (lrgst_expo - i));
|
|
130
|
|
131                     ans -= y_val;
|
|
132                     rank = (ans == 0) ? DBL_MAX : ABS(1 / ans);
|
|
133                 }
|
|
134             };
|
|
135         }
|
|
136
|
|
137         <emphasis role="keyword">using namespace </emphasis>detail;
|
|
141         <emphasis role="keyword">class </emphasis><link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>
|
|
142         {
|
|
143         <emphasis role="keyword">private</emphasis>:
|
|
144             <emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">short</emphasis> lrgst_expo; 
|
|
145             std::vector<int64_t> constants;
|
|
146
|
|
147             <emphasis role="keywordtype">bool</emphasis> bInitialized;
|
|
148
|
|
149             <emphasis role="keywordtype">void</emphasis> CanPerform()<emphasis role="keyword"> const </emphasis>{ <emphasis role="keywordflow">if</emphasis> (!bInitialized) <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Function object not initialized fully! Please call .SetConstants() to initialize"</emphasis>); }
|
|
150
|
|
151         <emphasis role="keyword">public</emphasis>:
|
|
152             <emphasis role="comment">// Speicialty function to get the real roots of a Quadratic Function without relying on a Genetic Algorithm to approximate</emphasis>
|
|
153             <emphasis role="keyword">friend</emphasis> std::vector<double> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a9d14c1b8a7401565a054837df5708ac8">QuadraticSolve</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f);
|
|
154
|
|
155         <emphasis role="keyword">public</emphasis>:
|
|
160             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a771e5f172d0738a6b56a3406ddea5779">Function</link>(<emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">short</emphasis>& Lrgst_expo) : lrgst_expo(Lrgst_expo), bInitialized(false)
|
|
161             {
|
|
162                 <emphasis role="keywordflow">if</emphasis> (lrgst_expo < 0)
|
|
163                     <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Function template argument must not be less than 0"</emphasis>); 
|
|
164                 constants.reserve(Lrgst_expo); 
|
|
165             }
|
|
167             <emphasis role="keyword">virtual</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1afc95333a173bc120f6f9519dae853b3a">~Function</link>();
|
|
169             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a2d7ac0d79af16746f89309f758adf40c">Function</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& other) = <emphasis role="keywordflow">default</emphasis>;
|
|
171             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a2f4cd78e5a95d1862b4389e81ef136da">Function</link>(<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>&& other) <emphasis role="keyword">noexcept</emphasis> = <emphasis role="keywordflow">default</emphasis>;
|
|
173             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a450305ad4a40a262d378b3781d87a043">operator=</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& other) = <emphasis role="keywordflow">default</emphasis>;
|
|
175             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1af58e47ffa93dc7dd6b336327058731ff">operator=</link>(<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>&& other) <emphasis role="keyword">noexcept</emphasis> = <emphasis role="keywordflow">default</emphasis>;
|
|
176
|
|
181             <emphasis role="keywordtype">void</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(<emphasis role="keyword">const</emphasis> std::vector<int64_t>& constnts);
|
|
186             <emphasis role="keywordtype">void</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(std::vector<int64_t>&& constnts);
|
|
187
|
|
188             <emphasis role="keyword">friend</emphasis> std::ostream& <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a9715ead4f7565aea73b2b956d32a8c2e">operator<<</link>(std::ostream& os, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> func);
|
|
189         
|
|
190             <emphasis role="keyword">friend</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac67d5be3dac9ab01eca47b11aaadb786">operator+</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f1, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f2);
|
|
191             <emphasis role="keyword">friend</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a5e5034306a381d48ef50cce10f8f76c8">operator-</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f1, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f2);
|
|
192
|
|
193             <emphasis role="keyword">friend</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a5bb4eeaf7c3f6efe1c4eb1cd128d0d5e">operator*</link>(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f, <emphasis role="keyword">const</emphasis> int64_t& c);
|
|
194             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a24f53f18a66c4911c9ec89f98b2f6781">operator*=</link>(<emphasis role="keyword">const</emphasis> int64_t& c);
|
|
195
|
|
200             [[nodiscard(<emphasis role="stringliteral">"MATH::EXP::Function::differential() returns the differential, the calling object is not changed"</emphasis>)]]
|
|
201             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1af05a7be6e85e4879185a84dc32cdf79c">differential</link>() <emphasis role="keyword">const</emphasis>;
|
|
202
|
|
208             [[nodiscard]] std::vector<double> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a2fe7e79ec57cb7160c783c20870fe855">get_real_roots</link>(<emphasis role="keyword">const</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>& options = <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>()) <emphasis role="keyword">const</emphasis>;
|
|
209
|
|
215             [[nodiscard]] <emphasis role="keywordtype">double</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a3df87946deead508714d3d6da50231ef">solve_y</link>(<emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">double</emphasis>& x_val) <emphasis role="keyword">const</emphasis>;
|
|
216
|
|
223             [[nodiscard]] std::vector<double> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac6f66aef23d97a47707796a9891fda80">solve_x</link>(<emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">double</emphasis>& y_val, <emphasis role="keyword">const</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>& options = <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>()) <emphasis role="keyword">const</emphasis>;
|
|
224
|
|
226             [[nodiscard]] <emphasis role="keyword">auto</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a8e355925ec8a283ad7a74a5c4832d4a8">GetWhatIsTheLargestExponent</link>()<emphasis role="keyword"> const </emphasis>{ <emphasis role="keywordflow">return</emphasis> lrgst_expo; }
|
|
227         };
|
|
228
|
|
234         std::vector<double> QuadraticSolve(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f)
|
|
235         {
|
|
236             <emphasis role="keywordflow">try</emphasis>
|
|
237             {
|
|
238                 <emphasis role="keywordflow">if</emphasis> (f.lrgst_expo != 2) <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Function f is not a quadratic function"</emphasis>);
|
|
239                 f.CanPerform();
|
|
240             }
|
|
241             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
242             {
|
|
243                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
244             }
|
|
245
|
|
246             std::vector<double> res;
|
|
247
|
|
248             <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& a = f.constants[0];
|
|
249             <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& b = f.constants[1];
|
|
250             <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& c = f.constants[2];
|
|
251
|
|
252             <emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">double</emphasis> sqr_val = <emphasis role="keyword">static_cast<</emphasis><emphasis role="keywordtype">double</emphasis><emphasis role="keyword">></emphasis>(POW(b, 2) - (4 * a * c));
|
|
253
|
|
254             <emphasis role="keywordflow">if</emphasis> (sqr_val < 0)
|
|
255             {
|
|
256                 <emphasis role="keywordflow">return</emphasis> res;
|
|
257             }
|
|
258
|
|
259             res.push_back(((NEGATE(b) + sqrt(sqr_val)) / 2 * a));
|
|
260             res.push_back(((NEGATE(b) - sqrt(sqr_val)) / 2 * a));
|
|
261             <emphasis role="keywordflow">return</emphasis> res;
|
|
262         }
|
|
263     
|
|
264         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1afc95333a173bc120f6f9519dae853b3a">Function::~Function</link>()
|
|
265         {
|
|
266             constants.clear();
|
|
267         }
|
|
268
|
|
269         <emphasis role="keywordtype">void</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">Function::SetConstants</link>(<emphasis role="keyword">const</emphasis> std::vector<int64_t>& constnts)
|
|
270         {
|
|
271             <emphasis role="keywordflow">if</emphasis> (constnts.size() != lrgst_expo + 1)
|
|
272                 <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Function<n> must be created with (n+1) integers in vector object"</emphasis>);
|
|
273
|
|
274             <emphasis role="keywordflow">if</emphasis> (constnts[0] == 0)
|
|
275                 <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"First value should not be 0"</emphasis>);
|
|
276
|
|
277             constants = constnts;
|
|
278             bInitialized = <emphasis role="keyword">true</emphasis>;
|
|
279         }
|
|
280
|
|
281         <emphasis role="keywordtype">void</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">Function::SetConstants</link>(std::vector<int64_t>&& constnts)
|
|
282         {
|
|
283             <emphasis role="keywordflow">if</emphasis> (constnts.size() != lrgst_expo + 1)
|
|
284                 <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Function<n> must be created with (n+1) integers in vector object"</emphasis>);
|
|
285
|
|
286             <emphasis role="keywordflow">if</emphasis> (constnts[0] == 0)
|
|
287                 <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"First value should not be 0"</emphasis>);
|
|
288
|
|
289             constants = std::move(constnts);
|
|
290             bInitialized = <emphasis role="keyword">true</emphasis>;
|
|
291         }
|
|
292
|
|
294         std::ostream& operator<<(std::ostream& os, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> func)
|
|
295         {
|
|
296             <emphasis role="keywordflow">try</emphasis>
|
|
297             {
|
|
298                 func.CanPerform();
|
|
299             }
|
|
300             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
301             {
|
|
302                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
303             }
|
|
304
|
|
305             <emphasis role="keywordflow">if</emphasis> (func.lrgst_expo == 0)
|
|
306             {
|
|
307                 os << func.constants[0];
|
|
308                 <emphasis role="keywordflow">return</emphasis> os;
|
|
309             }
|
|
310
|
|
311             <emphasis role="keywordflow">if</emphasis> (func.constants[0] == 1)
|
|
312                 os << <emphasis role="stringliteral">"x"</emphasis>;
|
|
313             <emphasis role="keywordflow">else</emphasis> <emphasis role="keywordflow">if</emphasis> (func.constants[0] == -1)
|
|
314                 os << <emphasis role="stringliteral">"-x"</emphasis>;
|
|
315             <emphasis role="keywordflow">else</emphasis>
|
|
316                 os << func.constants[0] << <emphasis role="stringliteral">"x"</emphasis>;
|
|
317
|
|
318             <emphasis role="keywordflow">if</emphasis> (func.lrgst_expo != 1)
|
|
319                 os << <emphasis role="stringliteral">"^"</emphasis> << func.lrgst_expo;
|
|
320
|
|
321             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis> i = func.lrgst_expo - 1; i > 0; i--)
|
|
322             {
|
|
323                 <emphasis role="keyword">auto</emphasis> n = func.constants[func.lrgst_expo - i];
|
|
324                 <emphasis role="keywordflow">if</emphasis> (n == 0) <emphasis role="keywordflow">continue</emphasis>;
|
|
325
|
|
326                 <emphasis role="keyword">auto</emphasis> s = n > 0 ? <emphasis role="stringliteral">" + "</emphasis> : <emphasis role="stringliteral">" - "</emphasis>;
|
|
327
|
|
328                 <emphasis role="keywordflow">if</emphasis> (n != 1)
|
|
329                     os << s << ABS(n) << <emphasis role="stringliteral">"x"</emphasis>;
|
|
330                 <emphasis role="keywordflow">else</emphasis>
|
|
331                     os << s << <emphasis role="stringliteral">"x"</emphasis>;
|
|
332
|
|
333                 <emphasis role="keywordflow">if</emphasis> (i != 1)
|
|
334                     os << <emphasis role="stringliteral">"^"</emphasis> << i;
|
|
335             }
|
|
336
|
|
337             <emphasis role="keyword">auto</emphasis> n = func.constants[func.lrgst_expo];
|
|
338             <emphasis role="keywordflow">if</emphasis> (n == 0) <emphasis role="keywordflow">return</emphasis> os;
|
|
339
|
|
340             <emphasis role="keyword">auto</emphasis> s = n > 0 ? <emphasis role="stringliteral">" + "</emphasis> : <emphasis role="stringliteral">" - "</emphasis>;
|
|
341             os << s;
|
|
342
|
|
343             os << ABS(n);
|
|
344
|
|
345             <emphasis role="keywordflow">return</emphasis> os;
|
|
346         }
|
|
347
|
|
349         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> operator+(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f1, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f2)
|
|
350         {
|
|
351             <emphasis role="keywordflow">try</emphasis>
|
|
352             {
|
|
353                 f1.CanPerform();
|
|
354                 f2.CanPerform();
|
|
355             }
|
|
356             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
357             {
|
|
358                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
359             }
|
|
360
|
|
361             <emphasis role="keyword">auto</emphasis> e1 = f1.lrgst_expo;
|
|
362             <emphasis role="keyword">auto</emphasis> e2 = f2.lrgst_expo;
|
|
363             <emphasis role="keyword">auto</emphasis> r = e1 > e2 ? e1 : e2;
|
|
364
|
|
365             std::vector<int64_t> res;
|
|
366             <emphasis role="keywordflow">if</emphasis> (e1 > e2)
|
|
367             {
|
|
368                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f1.constants)
|
|
369                     res.push_back(val);
|
|
370
|
|
371                 <emphasis role="keyword">auto</emphasis> i = e1 - e2;
|
|
372                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f2.constants)
|
|
373                 {
|
|
374                     res[i] += val;
|
|
375                     i++;
|
|
376                 }
|
|
377             }
|
|
378             <emphasis role="keywordflow">else</emphasis>
|
|
379             {
|
|
380                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f2.constants)
|
|
381                     res.push_back(val);
|
|
382
|
|
383                 <emphasis role="keywordtype">int</emphasis> i = e2 - e1;
|
|
384                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f1.constants)
|
|
385                 {
|
|
386                     res[i] += val;
|
|
387                     i++;
|
|
388                 }
|
|
389             }
|
|
390
|
|
391             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> f(r);
|
|
392             f.<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(res);
|
|
393             <emphasis role="keywordflow">return</emphasis> f;
|
|
394         }
|
|
395     
|
|
397         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> operator-(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f1, <emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f2)
|
|
398         {
|
|
399             <emphasis role="keywordflow">try</emphasis>
|
|
400             {
|
|
401                 f1.CanPerform();
|
|
402                 f2.CanPerform();
|
|
403             }
|
|
404             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
405             {
|
|
406                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
407             }
|
|
408
|
|
409             <emphasis role="keyword">auto</emphasis> e1 = f1.lrgst_expo;
|
|
410             <emphasis role="keyword">auto</emphasis> e2 = f2.lrgst_expo;
|
|
411             <emphasis role="keyword">auto</emphasis> r = e1 > e2 ? e1 : e2;
|
|
412
|
|
413             std::vector<int64_t> res;
|
|
414             <emphasis role="keywordflow">if</emphasis> (e1 > e2)
|
|
415             {
|
|
416                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f1.constants)
|
|
417                     res.push_back(val);
|
|
418
|
|
419                 <emphasis role="keyword">auto</emphasis> i = e1 - e2;
|
|
420                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f2.constants)
|
|
421                 {
|
|
422                     res[i] -= val;
|
|
423                     i++;
|
|
424                 }
|
|
425             }
|
|
426             <emphasis role="keywordflow">else</emphasis>
|
|
427             {
|
|
428                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f2.constants)
|
|
429                     res.push_back(val);
|
|
430
|
|
431                 <emphasis role="keywordtype">int</emphasis> i = e2 - e1;
|
|
432
|
|
433                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">int</emphasis> j = 0; j < i; j++)
|
|
434                     res[j] *= -1;
|
|
435
|
|
436                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f1.constants)
|
|
437                 {
|
|
438                     res[i] = val - res[i];
|
|
439                     i++;
|
|
440                 }
|
|
441             }
|
|
442
|
|
443             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> f(r);
|
|
444             f.<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(res);
|
|
445             <emphasis role="keywordflow">return</emphasis> f;
|
|
446         }
|
|
447
|
|
449         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> operator*(<emphasis role="keyword">const</emphasis> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& f, <emphasis role="keyword">const</emphasis> int64_t& c)
|
|
450         {
|
|
451             <emphasis role="keywordflow">try</emphasis>
|
|
452             {
|
|
453                 f.CanPerform();
|
|
454             }
|
|
455             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
456             {
|
|
457                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
458             }
|
|
459
|
|
460             <emphasis role="keywordflow">if</emphasis> (c == 1) <emphasis role="keywordflow">return</emphasis> f;
|
|
461             <emphasis role="keywordflow">if</emphasis> (c == 0) <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Cannot multiply a function by 0"</emphasis>);
|
|
462
|
|
463             std::vector<int64_t> res;
|
|
464             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : f.constants)
|
|
465                 res.push_back(c * val);
|
|
466
|
|
467             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> f_res(f.lrgst_expo);
|
|
468             f_res.<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(res);
|
|
469
|
|
470             <emphasis role="keywordflow">return</emphasis> f_res;
|
|
471         }
|
|
472
|
|
474         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link>& <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a24f53f18a66c4911c9ec89f98b2f6781">Function::operator*=</link>(<emphasis role="keyword">const</emphasis> int64_t& c)
|
|
475         {
|
|
476             <emphasis role="keywordflow">try</emphasis>
|
|
477             {
|
|
478                 this->CanPerform();
|
|
479             }
|
|
480             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
481             {
|
|
482                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
483             }
|
|
484
|
|
485             <emphasis role="keywordflow">if</emphasis> (c == 1) <emphasis role="keywordflow">return</emphasis> *<emphasis role="keyword">this</emphasis>;
|
|
486             <emphasis role="keywordflow">if</emphasis> (c == 0) <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Cannot multiply a function by 0"</emphasis>);
|
|
487
|
|
488             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& val : this->constants)
|
|
489                 val *= c;
|
|
490
|
|
491             <emphasis role="keywordflow">return</emphasis> *<emphasis role="keyword">this</emphasis>;
|
|
492         }
|
|
493         
|
|
494         <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1af05a7be6e85e4879185a84dc32cdf79c">Function::differential</link>()<emphasis role="keyword"> const</emphasis>
|
|
495 <emphasis role="keyword">        </emphasis>{
|
|
496             <emphasis role="keywordflow">try</emphasis>
|
|
497             {
|
|
498                 this->CanPerform();
|
|
499             }
|
|
500             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
501             {
|
|
502                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
503             }
|
|
504
|
|
505             <emphasis role="keywordflow">if</emphasis> (lrgst_expo == 0)
|
|
506                 <emphasis role="keywordflow">throw</emphasis> std::logic_error(<emphasis role="stringliteral">"Cannot differentiate a number (Function<0>)"</emphasis>);
|
|
507
|
|
508             std::vector<int64_t> result;
|
|
509             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">int</emphasis> i = 0; i < lrgst_expo; i++)
|
|
510             {
|
|
511                 result.push_back(constants[i] * (lrgst_expo - i));
|
|
512             }
|
|
513
|
|
514             <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function">Function</link> f{ (<emphasis role="keywordtype">unsigned</emphasis> short)(lrgst_expo - 1) };
|
|
515             f.<link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1ac27a8c4c7a6b39d087c8c20a63756cb3">SetConstants</link>(result);
|
|
516
|
|
517             <emphasis role="keywordflow">return</emphasis> f;
|
|
518         }
|
|
519
|
|
520         std::vector<double> <link linkend="_class_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_function_1a2fe7e79ec57cb7160c783c20870fe855">Function::get_real_roots</link>(<emphasis role="keyword">const</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>& options)<emphasis role="keyword"> const</emphasis>
|
|
521 <emphasis role="keyword">        </emphasis>{
|
|
522             <emphasis role="keywordflow">try</emphasis>
|
|
523             {
|
|
524                 this->CanPerform();
|
|
525             }
|
|
526             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
527             {
|
|
528                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
529             }
|
|
530
|
|
531             <emphasis role="comment">// Create initial random solutions</emphasis>
|
|
532             std::random_device device;
|
|
533             std::uniform_real_distribution<double> unif(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a316979973a2a6b70b00520c2f753a43c">min_range</link>, options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a9b8f1e5367f6b0d8b16eecaea53b40e2">max_range</link>);
|
|
534             std::vector<GA_Solution> solutions;
|
|
535
|
|
536             solutions.resize(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a6ec95fe6cc95dc32727659cf5bb1be12">data_size</link>);
|
|
537             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> i = 0; i < options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>; i++)
|
|
538                 solutions[i] = (GA_Solution{lrgst_expo, 0, unif(device)});
|
|
539
|
|
540             <emphasis role="keywordtype">float</emphasis> timer{ 0 };
|
|
541
|
|
542             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> count = 0; count < options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a4a67bad303f8a4fca40020a0802524c5">num_of_generations</link>; count++)
|
|
543             {
|
|
544                 std::generate(std::execution::par, solutions.begin() + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>, solutions.end(), [<emphasis role="keyword">this</emphasis>, &unif, &device]() {
|
|
545                     return GA_Solution{lrgst_expo, 0, unif(device)};
|
|
546                     });
|
|
547
|
|
548                 <emphasis role="comment">// Run our fitness function</emphasis>
|
|
549                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& s : solutions) { s.fitness(constants); }
|
|
550
|
|
551                 <emphasis role="comment">// Sort our solutions by rank</emphasis>
|
|
552                 std::sort(std::execution::par, solutions.begin(), solutions.end(),
|
|
553                     [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
554                         return lhs.rank > rhs.rank;
|
|
555                     });
|
|
556
|
|
557                 <emphasis role="comment">// Take top solutions</emphasis>
|
|
558                 std::vector<GA_Solution> sample;
|
|
559                 std::copy(
|
|
560                     solutions.begin(),
|
|
561                     solutions.begin() + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>,
|
|
562                     std::back_inserter(sample)
|
|
563                 );
|
|
564                 solutions.clear();
|
|
565
|
|
566                 <emphasis role="keywordflow">if</emphasis> (count + 1 == options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a4a67bad303f8a4fca40020a0802524c5">num_of_generations</link>)
|
|
567                 {
|
|
568                     std::copy(
|
|
569                         sample.begin(),
|
|
570                         sample.end(),
|
|
571                         std::back_inserter(solutions)
|
|
572                     );
|
|
573                     sample.clear();
|
|
574                     <emphasis role="keywordflow">break</emphasis>;
|
|
575                 }
|
|
576
|
|
577                 <emphasis role="comment">// Mutate the top solutions by %</emphasis>
|
|
578                 std::uniform_real_distribution<double> m((1 - options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a736488b3cfeebda7b93b3e8c6f576bf8">mutation_percentage</link>), (1 + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a736488b3cfeebda7b93b3e8c6f576bf8">mutation_percentage</link>));
|
|
579                 std::for_each(sample.begin(), sample.end(), [&m, &device](<emphasis role="keyword">auto</emphasis>& s) {
|
|
580                     s.x *= m(device);
|
|
581                     });
|
|
582
|
|
583                 <emphasis role="comment">// Cross over not needed as it's only one value</emphasis>
|
|
584
|
|
585                 std::copy(
|
|
586                     sample.begin(),
|
|
587                     sample.end(),
|
|
588                     std::back_inserter(solutions)
|
|
589                 );
|
|
590                 sample.clear();
|
|
591                 solutions.resize(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a6ec95fe6cc95dc32727659cf5bb1be12">data_size</link>);
|
|
592             }
|
|
593
|
|
594             std::sort(solutions.begin(), solutions.end(),
|
|
595                 [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
596                     return lhs.x < rhs.x;
|
|
597                 });
|
|
598
|
|
599             std::vector<double> ans;
|
|
600             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& s : solutions)
|
|
601             {
|
|
602                 ans.push_back(s.x);
|
|
603             }
|
|
604             <emphasis role="keywordflow">return</emphasis> ans;
|
|
605         }
|
|
606
|
|
607         <emphasis role="keywordtype">double</emphasis> Function::solve_y(<emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">double</emphasis>& x_val)<emphasis role="keyword"> const</emphasis>
|
|
608 <emphasis role="keyword">        </emphasis>{
|
|
609             <emphasis role="keywordflow">try</emphasis>
|
|
610             {
|
|
611                 this->CanPerform();
|
|
612             }
|
|
613             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
614             {
|
|
615                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
616             }
|
|
617
|
|
618             <emphasis role="keywordtype">double</emphasis> ans{ 0 };
|
|
619             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">int</emphasis> i = lrgst_expo; i >= 0; i--)
|
|
620             {
|
|
621                 ans += constants[i] * POW(x_val, (lrgst_expo - i));
|
|
622             }
|
|
623             <emphasis role="keywordflow">return</emphasis> ans;
|
|
624         }
|
|
625
|
|
626         <emphasis role="keyword">inline</emphasis> std::vector<double> Function::solve_x(<emphasis role="keyword">const</emphasis> <emphasis role="keywordtype">double</emphasis>& y_val, <emphasis role="keyword">const</emphasis> <link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options">GA_Options</link>& options)<emphasis role="keyword"> const</emphasis>
|
|
627 <emphasis role="keyword">        </emphasis>{
|
|
628             <emphasis role="keywordflow">try</emphasis>
|
|
629             {
|
|
630                 this->CanPerform();
|
|
631             }
|
|
632             <emphasis role="keywordflow">catch</emphasis> (<emphasis role="keyword">const</emphasis> std::exception& e)
|
|
633             {
|
|
634                 <emphasis role="keywordflow">throw</emphasis> e;
|
|
635             }
|
|
636
|
|
637             <emphasis role="comment">// Create initial random solutions</emphasis>
|
|
638             std::random_device device;
|
|
639             std::uniform_real_distribution<double> unif(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a316979973a2a6b70b00520c2f753a43c">min_range</link>, options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a9b8f1e5367f6b0d8b16eecaea53b40e2">max_range</link>);
|
|
640             std::vector<GA_Solution> solutions;
|
|
641
|
|
642             solutions.resize(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a6ec95fe6cc95dc32727659cf5bb1be12">data_size</link>);
|
|
643             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> i = 0; i < options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>; i++)
|
|
644                 solutions[i] = (GA_Solution{lrgst_expo, 0, unif(device), y_val});
|
|
645
|
|
646             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keywordtype">unsigned</emphasis> <emphasis role="keywordtype">int</emphasis> count = 0; count < options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a4a67bad303f8a4fca40020a0802524c5">num_of_generations</link>; count++)
|
|
647             {
|
|
648                 std::generate(std::execution::par, solutions.begin() + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>, solutions.end(), [<emphasis role="keyword">this</emphasis>, &unif, &device, &y_val]() {
|
|
649                     return GA_Solution{lrgst_expo, 0, unif(device), y_val};
|
|
650                     });
|
|
651
|
|
652
|
|
653                 <emphasis role="comment">// Run our fitness function</emphasis>
|
|
654                 <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& s : solutions) { s.fitness(constants); }
|
|
655
|
|
656                 <emphasis role="comment">// Sort our solutions by rank</emphasis>
|
|
657                 std::sort(std::execution::par, solutions.begin(), solutions.end(),
|
|
658                     [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
659                         return lhs.rank > rhs.rank;
|
|
660                     });
|
|
661
|
|
662                 <emphasis role="comment">// Take top solutions</emphasis>
|
|
663                 std::vector<GA_Solution> sample;
|
|
664                 std::copy(
|
|
665                     solutions.begin(),
|
|
666                     solutions.begin() + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1ad133af29dbbc26b8c3d507d359c03326">sample_size</link>,
|
|
667                     std::back_inserter(sample)
|
|
668                 );
|
|
669                 solutions.clear();
|
|
670
|
|
671                 <emphasis role="keywordflow">if</emphasis> (count + 1 == options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a4a67bad303f8a4fca40020a0802524c5">num_of_generations</link>)
|
|
672                 {
|
|
673                     std::copy(
|
|
674                         sample.begin(),
|
|
675                         sample.end(),
|
|
676                         std::back_inserter(solutions)
|
|
677                     );
|
|
678                     sample.clear();
|
|
679                     <emphasis role="keywordflow">break</emphasis>;
|
|
680                 }
|
|
681
|
|
682                 <emphasis role="comment">// Mutate the top solutions by %</emphasis>
|
|
683                 std::uniform_real_distribution<double> m((1 - options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a736488b3cfeebda7b93b3e8c6f576bf8">mutation_percentage</link>), (1 + options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a736488b3cfeebda7b93b3e8c6f576bf8">mutation_percentage</link>));
|
|
684                 std::for_each(sample.begin(), sample.end(), [&m, &device](<emphasis role="keyword">auto</emphasis>& s) {
|
|
685                     s.x *= m(device);
|
|
686                     });
|
|
687
|
|
688                 <emphasis role="comment">// Cross over not needed as it's only one value</emphasis>
|
|
689
|
|
690                 std::copy(
|
|
691                     sample.begin(),
|
|
692                     sample.end(),
|
|
693                     std::back_inserter(solutions)
|
|
694                 );
|
|
695                 sample.clear();
|
|
696                 solutions.resize(options.<link linkend="_struct_j_r_a_m_p_e_r_s_a_d_1_1_e_x_p_o_n_e_n_t_i_a_l_1_1_g_a___options_1a6ec95fe6cc95dc32727659cf5bb1be12">data_size</link>);
|
|
697             }
|
|
698
|
|
699             std::sort(solutions.begin(), solutions.end(),
|
|
700                 [](<emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& lhs, <emphasis role="keyword">const</emphasis> <emphasis role="keyword">auto</emphasis>& rhs) {
|
|
701                     return lhs.x < rhs.x;
|
|
702                 });
|
|
703
|
|
704             std::vector<double> ans;
|
|
705             <emphasis role="keywordflow">for</emphasis> (<emphasis role="keyword">auto</emphasis>& s : solutions)
|
|
706             {
|
|
707                 ans.push_back(s.x);
|
|
708             }
|
|
709             <emphasis role="keywordflow">return</emphasis> ans;
|
|
710         }
|
|
711     }
|
|
712 }
|
|
713
|
|
714 <emphasis role="preprocessor">#define INITIALIZE_EXPO_FUNCTION(func, ...) \</emphasis>
|
|
715 <emphasis role="preprocessor">func.SetConstants(__VA_ARGS__)</emphasis>
|
|
716
|
|
717 <emphasis role="preprocessor">#endif </emphasis><emphasis role="comment">// !JONATHAN_RAMPERSAD_EXPONENTIAL_H_</emphasis>
|
|
</programlisting></section>
|