From bff71bc1a535dec9ab1d4456ec894c2d8e0a1f17 Mon Sep 17 00:00:00 2001 From: Jonathan Rampersad Date: Tue, 5 Sep 2023 10:26:07 -0400 Subject: [PATCH] Rearranged functions to have more structure --- Exponential/FunctionsTemplate.h | 199 ++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 89 deletions(-) diff --git a/Exponential/FunctionsTemplate.h b/Exponential/FunctionsTemplate.h index 49fcb7b..ab6f446 100644 --- a/Exponential/FunctionsTemplate.h +++ b/Exponential/FunctionsTemplate.h @@ -151,6 +151,10 @@ namespace MATH private: std::vector constants; + public: + // Speicialty function to get the real roots of a Quadratic Function without relying on a Genetic Algorithm to approximate + friend std::vector QuadraticSolve(const Function<2>& f); + public: Function(const std::vector& constnts); Function(std::vector&& constnts); @@ -161,9 +165,6 @@ namespace MATH Function& operator=(const Function& other) = default; Function& operator=(Function&& other) noexcept = default; - [[nodiscard("MATH::EXP::Function::differential() returns the differential, the calling object is not changed")]] - Function differential() const; // This function returns the differential (dy/dx) of the Function object - // Operator function to display function object in a human readable format friend std::ostream& operator<<(std::ostream& os, const Function func) { @@ -210,9 +211,6 @@ namespace MATH return os; } - // Speicialty function to get the real roots of a Quadratic Function without relying on a Genetic Algorithm to approximate - friend std::vector QuadraticSolve(const Function<2>& f); - template friend Function operator+(const Function& f1, const Function& f2); // Operator to add two functions template @@ -232,12 +230,18 @@ namespace MATH } Function& 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) val *= c; return *this; } + [[nodiscard("MATH::EXP::Function::differential() returns the differential, the calling object is not changed")]] + Function 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 [[nodiscard]] std::vector get_real_roots_ga( 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 [[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 QuadraticSolve(const Function<2>& f) + { + std::vector 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(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 e2 ? e1 : e2)> + Function operator+(const Function& f1, const Function& f2) + { + std::vector 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{res}; + } + + template e2 ? e1 : e2)> + Function operator-(const Function& f1, const Function& f2) + { + std::vector 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{res}; + } + template Function::Function(const std::vector& constnts) { @@ -381,95 +475,22 @@ namespace MATH return ans; } - std::vector QuadraticSolve(const Function<2>& f) + template + double Function::solve_y(const double& x_val) const noexcept { - std::vector res; + std::vector exceptions; - const int& a = f.constants[0]; - const int& b = f.constants[1]; - const int& c = f.constants[2]; + for (int i : constants) + exceptions.push_back(i != 0); - const double sqr_val = static_cast(POW(b, 2) - (4 * a * c)); - - if (sqr_val < 0) + double ans{ 0 }; + for (int i = lrgst_exp; i >= 0; i--) { - return res; + if (exceptions[i]) + ans += constants[i] * POW(x_val, (lrgst_exp - i)); } - const double root1 = (NEGATE(b) + sqrt(sqr_val)) / 2 * a; - const double root2 = (NEGATE(b) - sqrt(sqr_val)) / 2 * a; - - res.push_back(root1); - res.push_back(root2); - return res; - } - - template e2 ? e1 : e2)> - Function operator+(const Function& f1, const Function& f2) - { - std::vector 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{res}; - } - - template e2 ? e1 : e2)> - Function operator-(const Function& f1, const Function& f2) - { - std::vector 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{res}; + return ans; } } } \ No newline at end of file