Advertisement
Guest User

Polynomial class

a guest
Dec 16th, 2017
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.10 KB | None | 0 0
  1. #include <vector>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include <cmath>
  7.  
  8. #define DEBUG
  9. #define DVIDING
  10.  
  11. template <class ScalarType>
  12. class Polynomial {
  13.  
  14. private:
  15.   std::vector<ScalarType> coefficients;
  16.  
  17.  
  18.   typename std::vector<ScalarType>::size_type degree() const;
  19.   typename std::vector<ScalarType>::iterator nc_begin();
  20.   typename std::vector<ScalarType>::iterator nc_end();
  21.   Polynomial<ScalarType> increaseDegree(int i) const;
  22.   bool isNull();
  23.  
  24.   void completeDivision(Polynomial<ScalarType>& divident,
  25.                         const Polynomial<ScalarType> &divisor,
  26.                         Polynomial<ScalarType>& remainder);
  27.  
  28.   ScalarType leadingCoefficient() const;
  29.  
  30. public:
  31.   Polynomial(const std::vector<ScalarType>& parameters);
  32.   Polynomial(const ScalarType& parameter);
  33.   Polynomial();
  34.   Polynomial(const Polynomial<ScalarType>& target);
  35.   template<class It> Polynomial(It first, It second);
  36.   typename std::vector<ScalarType>::size_type size() const;
  37.   ScalarType operator[] (int x);
  38.  
  39.  
  40.   template <class OtherScalar>
  41.   Polynomial<ScalarType> operator+ (const Polynomial<OtherScalar>& other) const;
  42.  
  43.   template <class OtherScalar>
  44.   Polynomial<ScalarType> operator+ (const OtherScalar& scalar) const;
  45.  
  46.   Polynomial<ScalarType> operator- (const Polynomial<ScalarType>& other) const;
  47.   Polynomial<ScalarType> operator- (const ScalarType& scalar) const;
  48.  
  49.   Polynomial<ScalarType> operator* (const Polynomial<ScalarType>& other) const;
  50.   Polynomial<ScalarType> operator* (const ScalarType& scalar) const;
  51.  
  52.   Polynomial<ScalarType> operator-= (const Polynomial<ScalarType>& other);
  53.   Polynomial<ScalarType> operator-= (const ScalarType& scalar);
  54.  
  55.   Polynomial<ScalarType> operator+= (const Polynomial<ScalarType>& other);
  56.   Polynomial<ScalarType> operator+= (const ScalarType& scalar);
  57.  
  58.   Polynomial<ScalarType> operator*= (const Polynomial<ScalarType>& other);
  59.   Polynomial<ScalarType> operator*= (const ScalarType& scalar);
  60.  
  61.   Polynomial<ScalarType> operator/ (const Polynomial<ScalarType>& divisor) const;
  62.   Polynomial<ScalarType> operator/ (const ScalarType& scalar) const;
  63.  
  64.   Polynomial<ScalarType> operator% (const Polynomial<ScalarType>& dvisor) const;
  65.   Polynomial<ScalarType> operator% (const ScalarType& dvisor) const;
  66.  
  67.   ScalarType operator() (const ScalarType& parameter) const;
  68.   ScalarType operator& (const Polynomial<ScalarType>& innerFunction) const;
  69.   Polynomial<ScalarType> operator^ (int power) const;
  70.  
  71.  
  72.   typename std::vector<ScalarType>::const_iterator begin() const;
  73.   typename std::vector<ScalarType>::const_iterator end() const;
  74.   typename std::vector<ScalarType> getCoefficients() const;
  75.   ScalarType getElement(int i) const;
  76.  
  77.   template <class inputScalar>
  78.   friend std::ostream& operator<< (std::ostream& os, const Polynomial<inputScalar>& input);
  79.  
  80. };
  81.  
  82. template <class ScalarType>
  83. Polynomial<ScalarType>::Polynomial(const std::vector<ScalarType>& parameters) {
  84.   this->coefficients = parameters;
  85. }
  86.  
  87. template <class ScalarType>
  88. Polynomial<ScalarType>::Polynomial(const Polynomial<ScalarType>& target) {
  89.   this->coefficients = target.getCoefficients();
  90. }
  91.  
  92. template <class ScalarType>
  93. Polynomial<ScalarType>::Polynomial() {
  94.   this->coefficients = {0};
  95. }
  96.  
  97. // ----------------
  98.  
  99. template <class ScalarType>
  100. typename std::vector<ScalarType>::iterator Polynomial<ScalarType>::nc_begin(){
  101.   return (this->coefficients.begin());
  102. }
  103.  
  104. template <class ScalarType>
  105. typename std::vector<ScalarType>::iterator Polynomial<ScalarType>::nc_end(){
  106.   return (this->coefficients.end());
  107. }
  108.  
  109. template <class ScalarType>
  110. typename std::vector<ScalarType>::size_type Polynomial<ScalarType>::size() const{
  111.   return (this->coefficients.size());
  112. }
  113.  
  114. template <class ScalarType>
  115. typename std::vector<ScalarType>::size_type Polynomial<ScalarType>::degree() const{
  116.   return (std::distance(this->begin,
  117.                         std::find_if_not(this->coefficients.rbegin(), this->coefficients.rend(),
  118.                         [](const ScalarType& input){return input == 0;})));
  119. }
  120.  
  121. template <class ScalarType>
  122. typename std::vector<ScalarType> Polynomial<ScalarType>::getCoefficients() const{
  123.   return (this->coefficients);
  124. }
  125.  
  126. template <class ScalarType>
  127. Polynomial<ScalarType> Polynomial<ScalarType>::increaseDegree(int x) const {
  128.   return(Polynomial(result(this->size() + x)));
  129. }
  130.  
  131. template <class ScalarType>
  132. ScalarType Polynomial<ScalarType>::leadingCoefficient() const {
  133.   return (*std::find_if_not(this->coefficients.rbegin(),
  134.                             this->coefficients.rend(),
  135.                             [](ScalarType& value){return(value != 0);}));
  136. }
  137.  
  138. template <class ScalarType>
  139. ScalarType Polynomial<ScalarType>::getElement(int i) const {
  140.   return(this->coefficients[i]);
  141. }
  142.  
  143. template <class ScalarType>
  144. bool Polynomial<ScalarType>::isNull() {
  145.   return (std::find_if_not(this->begin(),
  146.                            this->end(),
  147.                            [](const ScalarType& element){return element == 0;}));
  148. }
  149.  
  150. template <class ScalarType>
  151. void Polynomial<ScalarType>::completeDivision(Polynomial<ScalarType>& dividend,
  152.                                               const Polynomial<ScalarType>& divisor,
  153.                                               Polynomial<ScalarType>& remainder) {
  154.  
  155. //  Polynomial<ScalarType> quotient = Polynomial(0);
  156.   if (divisor.isNull()) {
  157.     return;
  158.   } else if (divisor.degree() > this->degree()) {
  159.     remainder = *this;
  160.     return;
  161.   } else {
  162.     while (dividend.degree() >= 0
  163.            && divisor.degree() <= dividend.degree()
  164.            && !dividend.isNull()) {
  165.  
  166.       int multDegree = dividend.degree() - divisor.degree();
  167.       ScalarType multCoefficient = dividend.leadingCoefficient() / divisor.leadingCoefficient();
  168.       dividend -= divisor.increaseDegree(multDegree) * multCoefficient;
  169.     }
  170.  
  171.     remainder = dividend;
  172.  
  173.     return;
  174.   }
  175. }
  176.  
  177. // ----------------
  178.  
  179. template <class ScalarType>
  180. typename std::vector<ScalarType>::const_iterator Polynomial<ScalarType>::begin() const{
  181.   return (this->coefficients.begin());
  182. }
  183.  
  184. template <class ScalarType>
  185. typename std::vector<ScalarType>::const_iterator Polynomial<ScalarType>::end() const{
  186.   return (this->coefficients.end());
  187. }
  188.  
  189. // ----------------
  190.  
  191. template <class inputScalar>
  192. std::ostream& operator << (std::ostream& os, const Polynomial<inputScalar>& input) {
  193.   std::string result;
  194.  
  195. #ifndef DEBUG
  196.  
  197.   result = std::to_string(*input.begin());
  198.  
  199.   for (int i = this->size() - 1; i > 0; --i) {
  200.     ScalarType value = input.coefficients[i];
  201.     if (value == 0) {
  202.       result += "";
  203.     } else if (value == 1) {
  204.       result += ( "+x^" + std::to_string(i));
  205.     } else if (value == -1) {
  206.       result += ( "-x^" + std::to_string(i));
  207.     } else {
  208.       result += (signbit(value) == 1 ? "+" : "") + std::to_string(value) + "x^" + std::to_string(i);
  209.     }
  210.   }
  211.  
  212. #else
  213.  
  214.   for (const inputScalar& value : input.coefficients) {
  215.     result += std::to_string(value) + " ";
  216.   }
  217.  
  218. #endif
  219.  
  220.   os << result;
  221.   return(os);
  222. }
  223.  
  224. template <class ScalarType>
  225. ScalarType Polynomial<ScalarType>::operator[] (int i) {
  226.   return (this->coefficients[i]);
  227. }
  228.  
  229. template <class ScalarType>
  230. Polynomial<ScalarType> Polynomial<ScalarType>::operator-= (const Polynomial<ScalarType>& other) {
  231.   *this = *this-other;
  232. }
  233.  
  234. template <class ScalarType>
  235. Polynomial<ScalarType> Polynomial<ScalarType>::operator-= (const ScalarType& scalar) {
  236.   *this = *this-scalar;
  237. }
  238.  
  239. template <class ScalarType>
  240. Polynomial<ScalarType> Polynomial<ScalarType>::operator+= (const Polynomial<ScalarType>& other) {
  241.   *this = *this + other;
  242. }
  243.  
  244. template <class ScalarType>
  245. Polynomial<ScalarType> Polynomial<ScalarType>::operator+= (const ScalarType& scalar) {
  246.   *this = *this - scalar;
  247. }
  248.  
  249. template <class ScalarType>
  250. Polynomial<ScalarType> Polynomial<ScalarType>::operator*= (const Polynomial<ScalarType>& other) {
  251.   *this = *this * other;
  252. }
  253.  
  254. template <class ScalarType>
  255. Polynomial<ScalarType> Polynomial<ScalarType>::operator*= (const ScalarType& scalar) {
  256.   *this = *this * scalar;
  257. }
  258.  
  259. template <class ScalarType>
  260. template <class OtherScalar>
  261. Polynomial<ScalarType> Polynomial<ScalarType>::operator+ (const OtherScalar& scalar) const {
  262.   Polynomial<ScalarType> result (*this);
  263.   *result.nc_begin() += scalar;
  264.   return (result);
  265. }
  266.  
  267. template <class ScalarType>
  268. template <class OtherScalar>
  269. Polynomial<ScalarType> Polynomial<ScalarType>::operator+ (const Polynomial<OtherScalar>& other) const {
  270.  
  271.   std::vector<ScalarType> summResult = this->getCoefficients();
  272.   std::vector<OtherScalar> toSumm = other.getCoefficients();
  273.  
  274.   std::transform(summResult.begin(),
  275.                  summResult.end(),
  276.                  toSumm.begin(),
  277.                  summResult.begin(),
  278.                  [](const ScalarType& first, const OtherScalar& second){return (first + second);});
  279.  
  280.   if (summResult.size() < toSumm.size()) {
  281.     summResult.insert(summResult.end(), toSumm.begin() + (toSumm.size() - summResult.size()), toSumm.end());
  282.   }
  283.  
  284.   return(Polynomial(summResult));
  285. }
  286.  
  287. template <class ScalarType>
  288. Polynomial<ScalarType> Polynomial<ScalarType>::operator* (const Polynomial<ScalarType>& other) const {
  289.   const int size = this->size() + other.size() - 1;
  290.  
  291.   std::vector<ScalarType> parameters(size);
  292.  
  293.   for (int i = 0; i < this->size(); ++i) {
  294.     for (int j = 0; j < other.size(); ++j) {
  295.       parameters[i + j] += this->getElement(i) * other.getElement(j);
  296.     }
  297.   }
  298.  
  299.   Polynomial<ScalarType> result(parameters);
  300.  
  301.   return(result);
  302. }
  303.  
  304. template <class ScalarType>
  305. Polynomial<ScalarType> Polynomial<ScalarType>::operator* (const ScalarType& scalar) const {
  306.   Polynomial<ScalarType> result (*this);
  307.   std::for_each(result.nc_begin(), result.nc_end(), [&](ScalarType &value){value *= scalar;});
  308.  
  309.   return (result);
  310. }
  311.  
  312. template <class ScalarType>
  313. Polynomial<ScalarType> Polynomial<ScalarType>::operator- (const ScalarType& scalar) const {
  314.   Polynomial<ScalarType> result (*this);
  315.   *result.nc_begin() -= scalar;
  316.   return (result);
  317. }
  318.  
  319. template <class ScalarType>
  320. Polynomial<ScalarType> Polynomial<ScalarType>::operator- (const Polynomial<ScalarType>& other) const {
  321.   return((other * -1) + *this);
  322. }
  323.  
  324. template <class ScalarType>
  325. Polynomial<ScalarType> Polynomial<ScalarType>::operator/ (const ScalarType& scalar) const {
  326.   std::vector<ScalarType> result(this->size());
  327.   std::transform(this->begin(), this->end(), result.begin(), [&](const ScalarType& value){return value/scalar;});
  328.   return (Polynomial(result));
  329. }
  330.  
  331. template <class ScalarType>
  332. Polynomial<ScalarType> Polynomial<ScalarType>::operator/ (const Polynomial<ScalarType>& divident) const {
  333.   Polynomial<ScalarType> divisionResult = *this;
  334.   Polynomial<ScalarType> remainder = Polynomial(0);
  335.   this->completeDivision(divisionResult, divident, remainder);
  336.   return(divisionResult);
  337. }
  338.  
  339. template <class ScalarType>
  340. Polynomial<ScalarType> Polynomial<ScalarType>::operator% (const Polynomial<ScalarType>& divident) const {
  341.   Polynomial<ScalarType> divisionResult = *this;
  342.   Polynomial<ScalarType> remainder = Polynomial(0);
  343.   this->completeDivision(divisionResult, divident, remainder);
  344.   return(remainder);
  345. }
  346.  
  347. template <class ScalarType>
  348. ScalarType Polynomial<ScalarType>::operator() (const ScalarType& parameter) const{
  349.   ScalarType result = 0;
  350.   for (int i = 0; i < this->size(); ++i) {
  351.     result += this->getElement(i) * std::pow(parameter, i);
  352.   }
  353.   return(result);
  354. }
  355.  
  356. template <class ScalarType>
  357. ScalarType Polynomial<ScalarType>::operator& (const Polynomial<ScalarType>& innerFunction) const {
  358.   Polynomial<ScalarType> result;
  359.   for (int i = 0; i < this->size(); ++i) {
  360.     result += *this->getElement(i) * (innerFunction^i);
  361.   }
  362.   return result;
  363. }
  364.  
  365. template <class ScalarType>
  366. Polynomial<ScalarType> Polynomial<ScalarType>::operator^ (int power) const {
  367.   Polynomial<ScalarType> result;
  368.   for (int i = 0; i < power; ++i) {
  369.     result *= *this;
  370.   }
  371.   return (result);
  372. }
  373.  
  374. using namespace std;
  375.  
  376. int main() {
  377.   std::vector<int> v = {2, 2, 2, 7, 0};
  378.   std::vector<float> f = {12.2, 12.3, 23.4};
  379.   Polynomial <int> test (v);
  380.   Polynomial <float> testF (f);
  381.   cout << testF + testF << endl;
  382.  
  383.   return 0;
  384. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement