2#ifndef JONATHAN_RAMPERSAD_EXPONENTIAL_H_
3#define JONATHAN_RAMPERSAD_EXPONENTIAL_H_
40 [[nodiscard(
"MATH::ABS(T) returns a value of type T")]] T ABS(
const T& n)
noexcept
42 return n < 0 ? n * -1 : n;
46 [[nodiscard(
"MATH::NEGATE(T) returns a value of type T")]] T NEGATE(
const T& n)
noexcept
52 [[nodiscard(
"MATH::POW(T, int) returns a value of type T")]] T POW(
const T& n,
const int& exp)
noexcept
58 for (
int i = 1; i < exp; i++)
67 [[nodiscard(
"MATH::SUM(std::vector<T>) returns a value of type T")]] T SUM(
const std::vector<T>& vec)
noexcept
76 [[nodiscard]] T MEDIAN(std::vector<T> vec)
noexcept
81 [](
const auto& lhs,
const auto& rhs) {
85 return vec[vec.size() / 2];
89 [[nodiscard]]
double MEAN(
const std::vector<T>& vec)
noexcept
91 return SUM(vec) / vec.size();
95 [[noreturn]]
void SortASC(std::vector<T>& vec)
99 vec.begin(), vec.end(),
100 [](
const auto& lhs,
const auto& rhs) {
106 [[noreturn]]
void SortDESC(std::vector<T>& vec)
110 vec.begin(), vec.end(),
111 [](
const auto& lhs,
const auto& rhs) {
116 template <
int lrgst_expo>
119 double rank, x, y_val;
122 GA_Solution() : rank(0), x(0), y_val(0), ranked(false) {}
123 GA_Solution(
double Rank,
double x_val,
double y = 0) : rank(Rank), x(x_val), y_val(y), ranked(false) {}
124 virtual ~GA_Solution() =
default;
126 void fitness(
const std::vector<int>& constants)
129 for (
int i = lrgst_expo; i >= 0; i--)
130 ans += constants[i] * POW(x, (lrgst_expo - i));
133 rank = (ans == 0) ? DBL_MAX : ABS(1 / ans);
138 using namespace detail;
143 template <
int lrgst_expo>
147 std::vector<int> constants;
158 Function(
const std::vector<int>& constnts);
163 Function(std::vector<int>&& constnts);
176 os << func.constants[0];
180 if (func.constants[0] == 1)
182 else if (func.constants[0] == -1)
185 os << func.constants[0] <<
"x";
188 os <<
"^" << lrgst_expo;
190 for (
int i = lrgst_expo - 1; i > 0; i--)
192 int n = func.constants[lrgst_expo - i];
193 if (n == 0)
continue;
195 auto s = n > 0 ?
" + " :
" - ";
198 os << s << ABS(n) <<
"x";
206 int n = func.constants[lrgst_expo];
207 if (n == 0)
return os;
209 auto s = n > 0 ?
" + " :
" - ";
217 template<
int e1,
int e2,
int r>
219 template<
int e1,
int e2,
int r>
225 if (c == 1)
return f;
226 if (c == 0)
throw std::logic_error(
"Cannot multiply a function by 0");
228 std::vector<int> res;
229 for (
auto& val : f.constants)
230 res.push_back(c * val);
236 if (
c == 1)
return *
this;
237 if (
c == 0)
throw std::logic_error(
"Cannot multiply a function by 0");
239 for (
auto&
val : this->constants)
249 [[
nodiscard(
"MATH::EXP::Function::differential() returns the differential, the calling object is not changed")]]
282 std::vector<double>
res;
284 const int&
a =
f.constants[0];
285 const int&
b =
f.constants[1];
286 const int&
c =
f.constants[2];
288 const double sqr_val =
static_cast<double>(POW(
b, 2) - (4 *
a *
c));
300 template<
int e1,
int e2,
int r = (e1 >
e2 ?
e1 :
e2)>
303 std::vector<int>
res;
306 for (
auto&
val :
f1.constants)
310 for (
auto&
val :
f2.constants)
318 for (
auto& val : f2.constants)
322 for (
auto& val : f1.constants)
329 return Function<r>{res};
332 template<
int e1,
int e2,
int r = (e1 > e2 ? e1 : e2)>
333 Function<r>
operator-(
const Function<e1>& f1,
const Function<e2>& f2)
335 std::vector<int> res;
338 for (
auto& val : f1.constants)
342 for (
auto& val : f2.constants)
350 for (
auto& val : f2.constants)
355 for (
int j = 0; j < i; j++)
358 for (
auto& val : f1.constants)
360 res[i] = val - res[i];
365 return Function<r>{res};
368 template <
int lrgst_expo>
372 throw std::logic_error(
"Function template argument must not be less than 0");
375 throw std::logic_error(
"Function<n> must be created with (n+1) integers in vector object");
378 throw std::logic_error(
"First value should not be 0");
383 template<
int lrgst_expo>
387 throw std::logic_error(
"Function template argument must not be less than 0");
390 throw std::logic_error(
"Function<n> must be created with (n+1) integers in vector object");
393 throw std::logic_error(
"First value should not be 0");
398 template <
int lrgst_expo>
404 template <
int lrgst_expo>
408 throw std::logic_error(
"Cannot differentiate a number (Function<0>)");
419 template<
int lrgst_expo>
423 std::random_device
device;
425 std::vector<GA_Solution<lrgst_expo>>
solutions;
428 for (
unsigned int i = 0;
i <
options.sample_size;
i++)
436 return GA_Solution<lrgst_expo>{0, unif(device)};
440 for (
auto&
s :
solutions) {
s.fitness(constants); }
444 [](
const auto&
lhs,
const auto&
rhs) {
445 return lhs.rank > rhs.rank;
449 std::vector<GA_Solution<lrgst_expo>>
sample;
453 std::back_inserter(
sample)
469 std::uniform_real_distribution<double>
m((1 -
options.mutation_percentage), (1 +
options.mutation_percentage));
486 [](
const auto&
lhs,
const auto&
rhs) {
487 return lhs.x < rhs.x;
490 std::vector<double>
ans;
498 template<
int lrgst_expo>
503 for (
int i : constants)
516 template<
int lrgst_expo>
520 std::random_device
device;
522 std::vector<GA_Solution<lrgst_expo>>
solutions;
525 for (
unsigned int i = 0;
i <
options.sample_size;
i++)
531 return GA_Solution<lrgst_expo>{0, unif(device), y_val};
536 for (
auto&
s :
solutions) {
s.fitness(constants); }
540 [](
const auto&
lhs,
const auto&
rhs) {
541 return lhs.rank > rhs.rank;
545 std::vector<GA_Solution<lrgst_expo>>
sample;
549 std::back_inserter(
sample)
565 std::uniform_real_distribution<double>
m((1 -
options.mutation_percentage), (1 +
options.mutation_percentage));
582 [](
const auto&
lhs,
const auto&
rhs) {
583 return lhs.x < rhs.x;
586 std::vector<double>
ans;
A class representing an Exponential Function (e.g 2x^2 + 4x - 1),.
Definition Exponential.h:145
std::vector< double > solve_x(const double &y_val, const GA_Options &options=GA_Options()) const
Function that uses a genetic algorithm to find the values of x where y = user value.
Definition Exponential.h:517
double solve_y(const double &x_val) const noexcept
Function that solves for y when x = user value.
Definition Exponential.h:499
friend std::vector< double > QuadraticSolve(const Function< 2 > &f)
Uses the quadratic function to solve the roots of an entered quadratic equation.
Definition Exponential.h:280
std::vector< double > get_real_roots(const GA_Options &options=GA_Options()) const
Function that uses a genetic algorithm to find the approximate roots of the function.
Definition Exponential.h:420
Function< lrgst_expo - 1 > differential() const
Calculates the differential (dy/dx) of the function.
Definition Exponential.h:405
Structure for options to be used when running one of the two genetic algorithms in a Function object.
Definition Exponential.h:22
double min_range
Minimum value you believe the answer can be.
Definition Exponential.h:24
unsigned int num_of_generations
Number of times you'd like to run the algorithm (increasing this value causes the algorithm to take l...
Definition Exponential.h:28
unsigned int data_size
Amount of solutions you'd like the algorithm to generate (increasing this value causes the algorithm ...
Definition Exponential.h:32
double mutation_percentage
How much you'd like the algorithm to mutate solutions (Leave this as default in most cases)
Definition Exponential.h:34
double max_range
Maximum value you believe the answer can be.
Definition Exponential.h:26
unsigned int sample_size
Amount of approximate solutions you'd like to be returned.
Definition Exponential.h:30