-
-
Save 30mb1/74858ef8af32b0419ce9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <map> | |
#include <utility> | |
#include <array> | |
#include <math.h> | |
template <typename T, int N> | |
class MultivariatePolynomial { | |
private: | |
std::map<std::array<int, N>, T> Monom; | |
public: | |
MultivariatePolynomial(std::map<std::array<int, N>, T> monom) { | |
for (auto x : monom) | |
if (x.second != 0) | |
Monom.insert(x); | |
} | |
MultivariatePolynomial(T koeff) { | |
std::array<int, N> null; | |
null.fill(0); | |
Monom[null] = koeff; | |
} | |
MultivariatePolynomial() { | |
std::map<std::array<int, N>, T> emptypoly; | |
Monom = emptypoly; | |
} | |
int operator () (std::array<T, N> point) { | |
int result = 0; | |
for (auto x : Monom) { | |
int mininom = 1; | |
for (size_t i = 0; i < N; i++) | |
mininom = mininom * pow(point[i], x.first[i]); | |
result = result + x.second * mininom; | |
} | |
return result; | |
} | |
friend bool operator == (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
if (poly.Monom == poly1.Monom) { | |
return true; | |
} return false; | |
} | |
friend bool operator == (MultivariatePolynomial<T, N> poly, T value) { | |
if (((poly.Monom.size() == 1) && ((((poly.Monom).begin())->second) == value)) || (poly.Monom.size() == 0)) { return true; } | |
else { return false; } | |
} | |
friend bool operator != (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
if (poly.Monom != poly1.Monom) { | |
return true; | |
} return false; | |
} | |
friend bool operator != (MultivariatePolynomial<T, N>& poly, T value) { | |
if ((poly.Monom.size() != 1) || ((((poly.Monom).begin())->second) != value)) { return true; } | |
else { return false; } | |
} | |
friend MultivariatePolynomial<T, N> operator + (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
MultivariatePolynomial<T, N> result = poly; | |
for (auto x2 : poly1.Monom) { | |
if ((result.Monom).find(x2.first) == (result.Monom).end()) { (result.Monom).insert(x2); } | |
else { | |
(result.Monom)[x2.first] += x2.second; | |
if ((result.Monom)[x2.first] == 0) { (result.Monom).erase(x2.first); } | |
} | |
} return result; | |
} | |
friend MultivariatePolynomial<T, N> operator - (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
MultivariatePolynomial<T, N> result = poly; | |
for (auto x2 : poly1.Monom) { | |
if ((result.Monom).find(x2.first) == (result.Monom).end()) { | |
x2.second *= -1; | |
(result.Monom).insert(x2); | |
} | |
else { | |
(result.Monom)[x2.first] -= x2.second; | |
if ((result.Monom)[x2.first] == 0) { (result.Monom).erase(x2.first); } | |
} | |
} return result; | |
} | |
friend void operator += (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
poly = poly + poly1; | |
} | |
friend void operator -= (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
poly = poly - poly1; | |
} | |
typename std::map<std::array<int, N>, T>::const_iterator begin() const { | |
return Monom.begin(); | |
} | |
typename std::map<std::array<int, N>, T>::const_iterator end() const { | |
return Monom.end(); | |
} | |
friend MultivariatePolynomial<T, N> operator * (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
MultivariatePolynomial<T, N> result; | |
std::pair<std::array<int, N>, T> buff; | |
for (auto x : poly.Monom) { | |
for (auto x2 : poly1.Monom) { | |
for (auto i = 0; i < N; i++) { | |
buff.first[i] = x.first[i] + x2.first[i]; | |
} buff.second = x.second * x2.second; | |
if ((result.Monom).find(buff.first) == (result.Monom).end()) { (result.Monom).insert(buff); } | |
else { (result.Monom)[buff.first] += buff.second; } | |
} | |
} return result; | |
} | |
friend void operator *= (MultivariatePolynomial<T, N>& poly, MultivariatePolynomial<T, N>& poly1) { | |
poly = poly * poly1; | |
} | |
friend void operator *= (MultivariatePolynomial<T, N>& poly, T value) { | |
MultivariatePolynomial<T, N> result; | |
for (auto x : poly.Monom) { | |
(result.Monom)[x.first] = x.second * value; | |
} poly = result; | |
} | |
int Degree() { | |
if (Monom.size() == 0) return 0; | |
int max = 0; | |
for (auto x : Monom) { | |
int summ = 0; | |
for (auto i = 0; i < N; i++) { | |
summ += x.first[i]; | |
} if (summ > max) { max = summ; } | |
} if (max == 0) { return -1; } | |
else { return max; } | |
} | |
friend std::ostream& operator << (std::ostream& out, MultivariatePolynomial<T, N> poly) { | |
if (poly.Monom.size() == 0) { out << "0"; return out; } | |
typename std::map<std::array<int, N>, T>::reverse_iterator x = (poly.Monom.rend()); | |
for (; x != (poly.Monom.rbegin()); x--) { | |
int numb = -1; | |
bool sum = false; | |
for (auto xx : x->first) | |
if (xx != 0) { | |
numb = numb + 1; | |
sum = true; | |
} | |
if (sum == false) { | |
if ((x->second < 0) || (x == (poly.Monom.rend()))) { out << x->second; } | |
else { out << "+" << x->second; } | |
} | |
else { | |
if ((x->second < -1) || ((x->second > 1) && (x == (poly.Monom.rend())))) { out << x->second << "*"; } | |
else if (x->second == -1) { out << "-"; } | |
else if ((x->second > 1) && (x != (poly.Monom.rend()))) { out << "+" << x->second << "*"; } | |
else if ((x->second == 1) && (x != (poly.Monom.rend()))) { out << "+"; } | |
for (auto xx = 0; xx != (x->first).size(); xx++) { | |
if (((x->first)[xx] > 1) || ((x->first)[xx] <= -1)) { out << "x" << xx << "^" << (x->first)[xx]; } | |
if ((x->first)[xx] == 1) { out << "x" << xx; } | |
if ((numb != 0) && ((x->first)[xx])) { | |
out << "*"; | |
numb -= 1; | |
} | |
} | |
} | |
} | |
return out; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment