Rearranged functions to have more structure
This commit is contained in:
@ -151,6 +151,10 @@ namespace MATH
|
|||||||
private:
|
private:
|
||||||
std::vector<int> constants;
|
std::vector<int> constants;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Speicialty function to get the real roots of a Quadratic Function without relying on a Genetic Algorithm to approximate
|
||||||
|
friend std::vector<double> QuadraticSolve(const Function<2>& f);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Function(const std::vector<int>& constnts);
|
Function(const std::vector<int>& constnts);
|
||||||
Function(std::vector<int>&& constnts);
|
Function(std::vector<int>&& constnts);
|
||||||
@ -161,9 +165,6 @@ namespace MATH
|
|||||||
Function& operator=(const Function& other) = default;
|
Function& operator=(const Function& other) = default;
|
||||||
Function& operator=(Function&& other) noexcept = default;
|
Function& operator=(Function&& other) noexcept = default;
|
||||||
|
|
||||||
[[nodiscard("MATH::EXP::Function::differential() returns the differential, the calling object is not changed")]]
|
|
||||||
Function<lrgst_exp - 1> differential() const; // This function returns the differential (dy/dx) of the Function object
|
|
||||||
|
|
||||||
// Operator function to display function object in a human readable format
|
// Operator function to display function object in a human readable format
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Function<lrgst_exp> func)
|
friend std::ostream& operator<<(std::ostream& os, const Function<lrgst_exp> func)
|
||||||
{
|
{
|
||||||
@ -210,9 +211,6 @@ namespace MATH
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Speicialty function to get the real roots of a Quadratic Function without relying on a Genetic Algorithm to approximate
|
|
||||||
friend std::vector<double> QuadraticSolve(const Function<2>& f);
|
|
||||||
|
|
||||||
template<int e1, int e2, int r>
|
template<int e1, int e2, int r>
|
||||||
friend Function<r> operator+(const Function<e1>& f1, const Function<e2>& f2); // Operator to add two functions
|
friend Function<r> operator+(const Function<e1>& f1, const Function<e2>& f2); // Operator to add two functions
|
||||||
template<int e1, int e2, int r>
|
template<int e1, int e2, int r>
|
||||||
@ -232,12 +230,18 @@ namespace MATH
|
|||||||
}
|
}
|
||||||
Function<lrgst_exp>& operator*=(const int& c)
|
Function<lrgst_exp>& operator*=(const int& c)
|
||||||
{
|
{
|
||||||
|
if (c == 1) return *this;
|
||||||
|
if (c == 0) throw std::logic_error("Cannot multiply a function by 0");
|
||||||
|
|
||||||
for (auto& val : this->constants)
|
for (auto& val : this->constants)
|
||||||
val *= c;
|
val *= c;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard("MATH::EXP::Function::differential() returns the differential, the calling object is not changed")]]
|
||||||
|
Function<lrgst_exp - 1> differential() const; // This function returns the differential (dy/dx) of the Function object
|
||||||
|
|
||||||
// Function that uses a genetic algorithm to find the approximate roots of the function
|
// Function that uses a genetic algorithm to find the approximate roots of the function
|
||||||
[[nodiscard]] std::vector<double> get_real_roots_ga(
|
[[nodiscard]] std::vector<double> get_real_roots_ga(
|
||||||
const double& min_range = GA_DEFAULT_MIN_RANGE,
|
const double& min_range = GA_DEFAULT_MIN_RANGE,
|
||||||
@ -250,8 +254,98 @@ namespace MATH
|
|||||||
// Function that returns the y-intercept of the function i.e. where x = 0
|
// Function that returns the y-intercept of the function i.e. where x = 0
|
||||||
[[nodiscard]] inline Coordinate2D get_y_intrcpt() const noexcept { return Coordinate2D{ 0, (double)constants[lrgst_exp] }; }
|
[[nodiscard]] inline Coordinate2D get_y_intrcpt() const noexcept { return Coordinate2D{ 0, (double)constants[lrgst_exp] }; }
|
||||||
|
|
||||||
|
[[nodiscard]] double solve_y(const double& x_val) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<double> QuadraticSolve(const Function<2>& f)
|
||||||
|
{
|
||||||
|
std::vector<double> res;
|
||||||
|
|
||||||
|
const int& a = f.constants[0];
|
||||||
|
const int& b = f.constants[1];
|
||||||
|
const int& c = f.constants[2];
|
||||||
|
|
||||||
|
const double sqr_val = static_cast<double>(POW(b, 2) - (4 * a * c));
|
||||||
|
|
||||||
|
if (sqr_val < 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.push_back( ((NEGATE(b) + sqrt(sqr_val)) / 2 * a) );
|
||||||
|
res.push_back( ((NEGATE(b) - sqrt(sqr_val)) / 2 * a) );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int e1, int e2, int r = (e1 > e2 ? e1 : e2)>
|
||||||
|
Function<r> operator+(const Function<e1>& f1, const Function<e2>& f2)
|
||||||
|
{
|
||||||
|
std::vector<int> res;
|
||||||
|
if (e1 > e2)
|
||||||
|
{
|
||||||
|
for (auto& val : f1.constants)
|
||||||
|
res.push_back(val);
|
||||||
|
|
||||||
|
int i = e1 - e2;
|
||||||
|
for (auto& val : f2.constants)
|
||||||
|
{
|
||||||
|
res[i] += val;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& val : f2.constants)
|
||||||
|
res.push_back(val);
|
||||||
|
|
||||||
|
int i = e2 - e1;
|
||||||
|
for (auto& val : f1.constants)
|
||||||
|
{
|
||||||
|
res[i] += val;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Function<r>{res};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int e1, int e2, int r = (e1 > e2 ? e1 : e2)>
|
||||||
|
Function<r> operator-(const Function<e1>& f1, const Function<e2>& f2)
|
||||||
|
{
|
||||||
|
std::vector<int> res;
|
||||||
|
if (e1 > e2)
|
||||||
|
{
|
||||||
|
for (auto& val : f1.constants)
|
||||||
|
res.push_back(val);
|
||||||
|
|
||||||
|
int i = e1 - e2;
|
||||||
|
for (auto& val : f2.constants)
|
||||||
|
{
|
||||||
|
res[i] -= val;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& val : f2.constants)
|
||||||
|
res.push_back(val);
|
||||||
|
|
||||||
|
int i = e2 - e1;
|
||||||
|
|
||||||
|
for (int j = 0; j < i; j++)
|
||||||
|
res[j] *= -1;
|
||||||
|
|
||||||
|
for (auto& val : f1.constants)
|
||||||
|
{
|
||||||
|
res[i] = val - res[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Function<r>{res};
|
||||||
|
}
|
||||||
|
|
||||||
template <int lrgst_exp>
|
template <int lrgst_exp>
|
||||||
Function<lrgst_exp>::Function(const std::vector<int>& constnts)
|
Function<lrgst_exp>::Function(const std::vector<int>& constnts)
|
||||||
{
|
{
|
||||||
@ -381,95 +475,22 @@ namespace MATH
|
|||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> QuadraticSolve(const Function<2>& f)
|
template<int lrgst_exp>
|
||||||
|
double Function<lrgst_exp>::solve_y(const double& x_val) const noexcept
|
||||||
{
|
{
|
||||||
std::vector<double> res;
|
std::vector<bool> exceptions;
|
||||||
|
|
||||||
const int& a = f.constants[0];
|
for (int i : constants)
|
||||||
const int& b = f.constants[1];
|
exceptions.push_back(i != 0);
|
||||||
const int& c = f.constants[2];
|
|
||||||
|
|
||||||
const double sqr_val = static_cast<double>(POW(b, 2) - (4 * a * c));
|
double ans{ 0 };
|
||||||
|
for (int i = lrgst_exp; i >= 0; i--)
|
||||||
if (sqr_val < 0)
|
|
||||||
{
|
{
|
||||||
return res;
|
if (exceptions[i])
|
||||||
|
ans += constants[i] * POW(x_val, (lrgst_exp - i));
|
||||||
}
|
}
|
||||||
|
|
||||||
const double root1 = (NEGATE(b) + sqrt(sqr_val)) / 2 * a;
|
return ans;
|
||||||
const double root2 = (NEGATE(b) - sqrt(sqr_val)) / 2 * a;
|
|
||||||
|
|
||||||
res.push_back(root1);
|
|
||||||
res.push_back(root2);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int e1, int e2, int r = (e1 > e2 ? e1 : e2)>
|
|
||||||
Function<r> operator+(const Function<e1>& f1, const Function<e2>& f2)
|
|
||||||
{
|
|
||||||
std::vector<int> res;
|
|
||||||
if (e1 > e2)
|
|
||||||
{
|
|
||||||
for (auto& val : f1.constants)
|
|
||||||
res.push_back(val);
|
|
||||||
|
|
||||||
int i = e1 - e2;
|
|
||||||
for (auto& val : f2.constants)
|
|
||||||
{
|
|
||||||
res[i] += val;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto& val : f2.constants)
|
|
||||||
res.push_back(val);
|
|
||||||
|
|
||||||
int i = e2 - e1;
|
|
||||||
for (auto& val : f1.constants)
|
|
||||||
{
|
|
||||||
res[i] += val;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Function<r>{res};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int e1, int e2, int r = (e1 > e2 ? e1 : e2)>
|
|
||||||
Function<r> operator-(const Function<e1>& f1, const Function<e2>& f2)
|
|
||||||
{
|
|
||||||
std::vector<int> res;
|
|
||||||
if (e1 > e2)
|
|
||||||
{
|
|
||||||
for (auto& val : f1.constants)
|
|
||||||
res.push_back(val);
|
|
||||||
|
|
||||||
int i = e1 - e2;
|
|
||||||
for (auto& val : f2.constants)
|
|
||||||
{
|
|
||||||
res[i] -= val;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto& val : f2.constants)
|
|
||||||
res.push_back(val);
|
|
||||||
|
|
||||||
int i = e2 - e1;
|
|
||||||
|
|
||||||
for (int j = 0; j < i; j++)
|
|
||||||
res[j] *= -1;
|
|
||||||
|
|
||||||
for (auto& val : f1.constants)
|
|
||||||
{
|
|
||||||
res[i] = val - res[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Function<r>{res};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user