Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <iostream>
- #include <iterator>
- #include <sstream>
- #include <algorithm>
- #include <cmath>
- #define DEBUG
- #define DVIDING
- template <class ScalarType>
- class Polynomial {
- private:
- std::vector<ScalarType> coefficients;
- typename std::vector<ScalarType>::size_type degree() const;
- typename std::vector<ScalarType>::iterator nc_begin();
- typename std::vector<ScalarType>::iterator nc_end();
- Polynomial<ScalarType> increaseDegree(int i) const;
- bool isNull();
- void completeDivision(Polynomial<ScalarType>& divident,
- const Polynomial<ScalarType> &divisor,
- Polynomial<ScalarType>& remainder);
- ScalarType leadingCoefficient() const;
- public:
- Polynomial(const std::vector<ScalarType>& parameters);
- Polynomial(const ScalarType& parameter);
- Polynomial();
- Polynomial(const Polynomial<ScalarType>& target);
- template<class It> Polynomial(It first, It second);
- typename std::vector<ScalarType>::size_type size() const;
- ScalarType operator[] (int x);
- template <class OtherScalar>
- Polynomial<ScalarType> operator+ (const Polynomial<OtherScalar>& other) const;
- template <class OtherScalar>
- Polynomial<ScalarType> operator+ (const OtherScalar& scalar) const;
- Polynomial<ScalarType> operator- (const Polynomial<ScalarType>& other) const;
- Polynomial<ScalarType> operator- (const ScalarType& scalar) const;
- Polynomial<ScalarType> operator* (const Polynomial<ScalarType>& other) const;
- Polynomial<ScalarType> operator* (const ScalarType& scalar) const;
- Polynomial<ScalarType> operator-= (const Polynomial<ScalarType>& other);
- Polynomial<ScalarType> operator-= (const ScalarType& scalar);
- Polynomial<ScalarType> operator+= (const Polynomial<ScalarType>& other);
- Polynomial<ScalarType> operator+= (const ScalarType& scalar);
- Polynomial<ScalarType> operator*= (const Polynomial<ScalarType>& other);
- Polynomial<ScalarType> operator*= (const ScalarType& scalar);
- Polynomial<ScalarType> operator/ (const Polynomial<ScalarType>& divisor) const;
- Polynomial<ScalarType> operator/ (const ScalarType& scalar) const;
- Polynomial<ScalarType> operator% (const Polynomial<ScalarType>& dvisor) const;
- Polynomial<ScalarType> operator% (const ScalarType& dvisor) const;
- ScalarType operator() (const ScalarType& parameter) const;
- ScalarType operator& (const Polynomial<ScalarType>& innerFunction) const;
- Polynomial<ScalarType> operator^ (int power) const;
- typename std::vector<ScalarType>::const_iterator begin() const;
- typename std::vector<ScalarType>::const_iterator end() const;
- typename std::vector<ScalarType> getCoefficients() const;
- ScalarType getElement(int i) const;
- template <class inputScalar>
- friend std::ostream& operator<< (std::ostream& os, const Polynomial<inputScalar>& input);
- };
- template <class ScalarType>
- Polynomial<ScalarType>::Polynomial(const std::vector<ScalarType>& parameters) {
- this->coefficients = parameters;
- }
- template <class ScalarType>
- Polynomial<ScalarType>::Polynomial(const Polynomial<ScalarType>& target) {
- this->coefficients = target.getCoefficients();
- }
- template <class ScalarType>
- Polynomial<ScalarType>::Polynomial() {
- this->coefficients = {0};
- }
- // ----------------
- template <class ScalarType>
- typename std::vector<ScalarType>::iterator Polynomial<ScalarType>::nc_begin(){
- return (this->coefficients.begin());
- }
- template <class ScalarType>
- typename std::vector<ScalarType>::iterator Polynomial<ScalarType>::nc_end(){
- return (this->coefficients.end());
- }
- template <class ScalarType>
- typename std::vector<ScalarType>::size_type Polynomial<ScalarType>::size() const{
- return (this->coefficients.size());
- }
- template <class ScalarType>
- typename std::vector<ScalarType>::size_type Polynomial<ScalarType>::degree() const{
- return (std::distance(this->begin,
- std::find_if_not(this->coefficients.rbegin(), this->coefficients.rend(),
- [](const ScalarType& input){return input == 0;})));
- }
- template <class ScalarType>
- typename std::vector<ScalarType> Polynomial<ScalarType>::getCoefficients() const{
- return (this->coefficients);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::increaseDegree(int x) const {
- return(Polynomial(result(this->size() + x)));
- }
- template <class ScalarType>
- ScalarType Polynomial<ScalarType>::leadingCoefficient() const {
- return (*std::find_if_not(this->coefficients.rbegin(),
- this->coefficients.rend(),
- [](ScalarType& value){return(value != 0);}));
- }
- template <class ScalarType>
- ScalarType Polynomial<ScalarType>::getElement(int i) const {
- return(this->coefficients[i]);
- }
- template <class ScalarType>
- bool Polynomial<ScalarType>::isNull() {
- return (std::find_if_not(this->begin(),
- this->end(),
- [](const ScalarType& element){return element == 0;}));
- }
- template <class ScalarType>
- void Polynomial<ScalarType>::completeDivision(Polynomial<ScalarType>& dividend,
- const Polynomial<ScalarType>& divisor,
- Polynomial<ScalarType>& remainder) {
- // Polynomial<ScalarType> quotient = Polynomial(0);
- if (divisor.isNull()) {
- return;
- } else if (divisor.degree() > this->degree()) {
- remainder = *this;
- return;
- } else {
- while (dividend.degree() >= 0
- && divisor.degree() <= dividend.degree()
- && !dividend.isNull()) {
- int multDegree = dividend.degree() - divisor.degree();
- ScalarType multCoefficient = dividend.leadingCoefficient() / divisor.leadingCoefficient();
- dividend -= divisor.increaseDegree(multDegree) * multCoefficient;
- }
- remainder = dividend;
- return;
- }
- }
- // ----------------
- template <class ScalarType>
- typename std::vector<ScalarType>::const_iterator Polynomial<ScalarType>::begin() const{
- return (this->coefficients.begin());
- }
- template <class ScalarType>
- typename std::vector<ScalarType>::const_iterator Polynomial<ScalarType>::end() const{
- return (this->coefficients.end());
- }
- // ----------------
- template <class inputScalar>
- std::ostream& operator << (std::ostream& os, const Polynomial<inputScalar>& input) {
- std::string result;
- #ifndef DEBUG
- result = std::to_string(*input.begin());
- for (int i = this->size() - 1; i > 0; --i) {
- ScalarType value = input.coefficients[i];
- if (value == 0) {
- result += "";
- } else if (value == 1) {
- result += ( "+x^" + std::to_string(i));
- } else if (value == -1) {
- result += ( "-x^" + std::to_string(i));
- } else {
- result += (signbit(value) == 1 ? "+" : "") + std::to_string(value) + "x^" + std::to_string(i);
- }
- }
- #else
- for (const inputScalar& value : input.coefficients) {
- result += std::to_string(value) + " ";
- }
- #endif
- os << result;
- return(os);
- }
- template <class ScalarType>
- ScalarType Polynomial<ScalarType>::operator[] (int i) {
- return (this->coefficients[i]);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator-= (const Polynomial<ScalarType>& other) {
- *this = *this-other;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator-= (const ScalarType& scalar) {
- *this = *this-scalar;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator+= (const Polynomial<ScalarType>& other) {
- *this = *this + other;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator+= (const ScalarType& scalar) {
- *this = *this - scalar;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator*= (const Polynomial<ScalarType>& other) {
- *this = *this * other;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator*= (const ScalarType& scalar) {
- *this = *this * scalar;
- }
- template <class ScalarType>
- template <class OtherScalar>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator+ (const OtherScalar& scalar) const {
- Polynomial<ScalarType> result (*this);
- *result.nc_begin() += scalar;
- return (result);
- }
- template <class ScalarType>
- template <class OtherScalar>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator+ (const Polynomial<OtherScalar>& other) const {
- std::vector<ScalarType> summResult = this->getCoefficients();
- std::vector<OtherScalar> toSumm = other.getCoefficients();
- std::transform(summResult.begin(),
- summResult.end(),
- toSumm.begin(),
- summResult.begin(),
- [](const ScalarType& first, const OtherScalar& second){return (first + second);});
- if (summResult.size() < toSumm.size()) {
- summResult.insert(summResult.end(), toSumm.begin() + (toSumm.size() - summResult.size()), toSumm.end());
- }
- return(Polynomial(summResult));
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator* (const Polynomial<ScalarType>& other) const {
- const int size = this->size() + other.size() - 1;
- std::vector<ScalarType> parameters(size);
- for (int i = 0; i < this->size(); ++i) {
- for (int j = 0; j < other.size(); ++j) {
- parameters[i + j] += this->getElement(i) * other.getElement(j);
- }
- }
- Polynomial<ScalarType> result(parameters);
- return(result);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator* (const ScalarType& scalar) const {
- Polynomial<ScalarType> result (*this);
- std::for_each(result.nc_begin(), result.nc_end(), [&](ScalarType &value){value *= scalar;});
- return (result);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator- (const ScalarType& scalar) const {
- Polynomial<ScalarType> result (*this);
- *result.nc_begin() -= scalar;
- return (result);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator- (const Polynomial<ScalarType>& other) const {
- return((other * -1) + *this);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator/ (const ScalarType& scalar) const {
- std::vector<ScalarType> result(this->size());
- std::transform(this->begin(), this->end(), result.begin(), [&](const ScalarType& value){return value/scalar;});
- return (Polynomial(result));
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator/ (const Polynomial<ScalarType>& divident) const {
- Polynomial<ScalarType> divisionResult = *this;
- Polynomial<ScalarType> remainder = Polynomial(0);
- this->completeDivision(divisionResult, divident, remainder);
- return(divisionResult);
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator% (const Polynomial<ScalarType>& divident) const {
- Polynomial<ScalarType> divisionResult = *this;
- Polynomial<ScalarType> remainder = Polynomial(0);
- this->completeDivision(divisionResult, divident, remainder);
- return(remainder);
- }
- template <class ScalarType>
- ScalarType Polynomial<ScalarType>::operator() (const ScalarType& parameter) const{
- ScalarType result = 0;
- for (int i = 0; i < this->size(); ++i) {
- result += this->getElement(i) * std::pow(parameter, i);
- }
- return(result);
- }
- template <class ScalarType>
- ScalarType Polynomial<ScalarType>::operator& (const Polynomial<ScalarType>& innerFunction) const {
- Polynomial<ScalarType> result;
- for (int i = 0; i < this->size(); ++i) {
- result += *this->getElement(i) * (innerFunction^i);
- }
- return result;
- }
- template <class ScalarType>
- Polynomial<ScalarType> Polynomial<ScalarType>::operator^ (int power) const {
- Polynomial<ScalarType> result;
- for (int i = 0; i < power; ++i) {
- result *= *this;
- }
- return (result);
- }
- using namespace std;
- int main() {
- std::vector<int> v = {2, 2, 2, 7, 0};
- std::vector<float> f = {12.2, 12.3, 23.4};
- Polynomial <int> test (v);
- Polynomial <float> testF (f);
- cout << testF + testF << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement