Skip to content

Instantly share code, notes, and snippets.

@30mb1
Created December 14, 2015 14:44
Show Gist options
  • Save 30mb1/74858ef8af32b0419ce9 to your computer and use it in GitHub Desktop.
Save 30mb1/74858ef8af32b0419ce9 to your computer and use it in GitHub Desktop.
#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