Created
January 21, 2018 21:37
-
-
Save pacmancoder/4ecf15365086456adfeca0a3ec2b6ea2 to your computer and use it in GitHub Desktop.
Polynomial
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 <Polynomial.h> | |
#include <string> | |
#include <vector> | |
#include <fstream> | |
#include <ios> | |
using namespace Calculus; | |
namespace | |
{ | |
const char* DEFAULT_VARIABLES_FILE("variables.bin"); | |
void ClearCin() | |
{ | |
size_t MAX_IGNORE_CHARS(10000); | |
std::cin.clear(); | |
std::cin.ignore(MAX_IGNORE_CHARS, '\n'); | |
} | |
char SelectOption() | |
{ | |
std::cout << "option > "; | |
char option = 0; | |
std::cin >> option; | |
ClearCin(); | |
return option; | |
} | |
size_t SelectVariable() | |
{ | |
char index = 0; | |
for(;;) | |
{ | |
std::cout << "variable index > "; | |
std::cin >> index; | |
if (index < '0' || index > '9') | |
{ | |
std::cout << "Please provide value from 0 to 9" << std::endl; | |
ClearCin(); | |
continue; | |
} | |
ClearCin(); | |
return static_cast<size_t >(index - '0'); | |
} | |
} | |
Polynomial::Exponent SelectExponent() | |
{ | |
Polynomial::Exponent exponent = 0; | |
for (;;) | |
{ | |
std::cout << "exponent (order) > "; | |
if (std::cin >> exponent) | |
{ | |
ClearCin(); | |
return exponent; | |
} | |
std::cout << "Please provide valid integer!" << std::endl; | |
ClearCin(); | |
} | |
} | |
Polynomial::Scale SelectScale() | |
{ | |
Polynomial::Scale scale = 0; | |
for (;;) | |
{ | |
std::cout << "scale (coefficient) > "; | |
if (std::cin >> scale) | |
{ | |
ClearCin(); | |
return scale; | |
} | |
std::cout << "Please provide valid float!" << std::endl; | |
ClearCin(); | |
} | |
} | |
void DisplayVariables(const std::vector<Polynomial>& variables) | |
{ | |
for (size_t i = 0; i < variables.size(); ++i) | |
{ | |
std::cout << "[" << i << "] : " << variables[i].toString() << std::endl; | |
} | |
} | |
void AddMemberToPolynomial(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
Polynomial::Exponent exponent = SelectExponent(); | |
Polynomial::Scale scale = SelectScale(); | |
variables[variable][exponent] = scale; | |
} | |
void CopyVariable(std::vector<Polynomial>& variables) | |
{ | |
std::cout << "Form:" << std::endl; | |
auto from = SelectVariable(); | |
std::cout << "To:" << std::endl; | |
auto to = SelectVariable(); | |
variables[to] = variables[from]; | |
} | |
void MultiplyByConst(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::cout << "Scale:" << std::endl; | |
auto scale = SelectScale(); | |
variables[variable] = variables[variable] * scale; | |
} | |
void DivideByConst(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::cout << "Divisor:" << std::endl; | |
auto scale = SelectScale(); | |
variables[variable] = variables[variable] / scale; | |
} | |
void Multiply(std::vector<Polynomial>& variables) | |
{ | |
std::cout << "Variable 1:" << std::endl; | |
auto variable1 = SelectVariable(); | |
std::cout << "Variable 2:" << std::endl; | |
auto variable2 = SelectVariable(); | |
std::cout << "Resulting variable:" << std::endl; | |
auto result = SelectVariable(); | |
variables[result] = variables[variable1] * variables[variable2]; | |
} | |
void Add(std::vector<Polynomial>& variables) | |
{ | |
std::cout << "Variable 1:" << std::endl; | |
auto variable1 = SelectVariable(); | |
std::cout << "Variable 2:" << std::endl; | |
auto variable2 = SelectVariable(); | |
std::cout << "Resulting variable:" << std::endl; | |
auto result = SelectVariable(); | |
variables[result] = variables[variable1] + variables[variable2]; | |
} | |
void PowerOfPolynomial(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::cout << "Exponent:" << std::endl; | |
auto exp = SelectExponent(); | |
variables[variable] = variables[variable] ^ exp; | |
} | |
void SetScaleForRange(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::cout << "Lowest exponent:" << std::endl; | |
auto from = SelectExponent(); | |
std::cout << "Highest exponent:" << std::endl; | |
auto to = SelectExponent(); | |
std::cout << "Scale:" << std::endl; | |
auto scale = SelectScale(); | |
variables[variable](from, to) = scale; | |
} | |
void LoadVariables(std::vector<Polynomial>& variables) | |
{ | |
std::ifstream file(DEFAULT_VARIABLES_FILE, std::ios::binary | std::ios::in); | |
for (auto& v : variables) | |
{ | |
file >> v; | |
} | |
} | |
void SaveVariables(const std::vector<Polynomial>& variables) | |
{ | |
std::ofstream file(DEFAULT_VARIABLES_FILE, std::ios::binary | std::ios::out | std::ios::trunc); | |
for (const auto& v : variables) | |
{ | |
file << v; | |
} | |
} | |
void Evaluate(const std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::cout << "Enter value for variable:" << std::endl; | |
auto value = SelectScale(); | |
std::cout << "Result: " << variables[variable].toString() << " = " << variables[variable](value) << std::endl; | |
} | |
void ChangeIdentifier(std::vector<Polynomial>& variables) | |
{ | |
auto variable = SelectVariable(); | |
std::string identifier; | |
std::cout << "Enter identifier (one char):" << std::endl; | |
identifier.push_back(SelectOption()); | |
variables[variable].setVariableName(identifier); | |
} | |
void ShowMenu() | |
{ | |
std::cout << "=== Select action with key ===" << std::endl; | |
std::cout << "d - Display current variables" << std::endl; | |
std::cout << "a - Set single member of polynomial" << std::endl; | |
std::cout << "c - Copy variable" << std::endl; | |
std::cout << "q - Exit from application" << std::endl; | |
std::cout << "r - Set scale for the range of the members" << std::endl; | |
std::cout << "u - Multiply on constant" << std::endl; | |
std::cout << "l - Divide on constant" << std::endl; | |
std::cout << "p - Raise polynomial to power" << std::endl; | |
std::cout << "m - Multiply 2 polynomials" << std::endl; | |
std::cout << "s - Sum 2 polynomials" << std::endl; | |
std::cout << "o - Save variables to file" << std::endl; | |
std::cout << "i - Load variables from file" << std::endl; | |
std::cout << "e - Evaluate polynomial in point" << std::endl; | |
std::cout << "v - Change default variable identifier" << std::endl; | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
std::vector<Polynomial> variables(10); | |
bool exitRequested = false; | |
for(;;) | |
{ | |
ShowMenu(); | |
auto option = SelectOption(); | |
switch (option) | |
{ | |
case 'd': DisplayVariables(variables); break; | |
case 'a': AddMemberToPolynomial(variables); break; | |
case 'c': CopyVariable(variables); break; | |
case 'r': SetScaleForRange(variables); break; | |
case 'u': MultiplyByConst(variables); break; | |
case 'l': DivideByConst(variables); break; | |
case 'p': PowerOfPolynomial(variables); break; | |
case 'm': Multiply(variables); break; | |
case 's': Add(variables); break; | |
case 'o': SaveVariables(variables); break; | |
case 'i': LoadVariables(variables); break; | |
case 'e': Evaluate(variables); break; | |
case 'v': ChangeIdentifier(variables); break; | |
case 'q': exitRequested = true; break; | |
default: break; | |
} | |
if (exitRequested) | |
{ | |
break; | |
} | |
std::cout << std::endl; | |
} | |
return 0; | |
} |
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 <Polynomial.h> | |
#include <sstream> | |
#include <cmath> | |
using namespace Calculus; | |
Polynomial::Polynomial() : | |
Polynomial(PolynomialMap()) {} | |
Polynomial::Polynomial(const Polynomial::PolynomialMap& polyMap) : | |
variableName_("x"), poly_(polyMap) {} | |
Polynomial::Polynomial(const Polynomial& rhs) : | |
variableName_(rhs.variableName_), poly_(rhs.poly_) {} | |
Polynomial::Polynomial(std::istream& stream) | |
{ | |
deserialize(stream); | |
} | |
Polynomial& Polynomial::operator=(const Polynomial& rhs) | |
{ | |
variableName_ = rhs.variableName_; | |
poly_ = rhs.poly_; | |
return *this; | |
} | |
Polynomial::Scale& Polynomial::operator[](size_t order) | |
{ | |
// operator [] for map will always construct default value (in our case - scale which equals 0) | |
return poly_[order]; | |
} | |
Polynomial::PolynomialMap &Polynomial::operator->() | |
{ | |
return poly_; | |
} | |
std::string Polynomial::toString() const | |
{ | |
std::stringstream stringStream; | |
bool isFirst = true; | |
for (const auto& f : poly_) | |
{ | |
if (!isFirst) | |
{ | |
stringStream << " "; | |
} | |
// scale is zero -- shouldn't be displayed | |
if (f.second == 0) | |
{ | |
continue; | |
} | |
// display sign | |
if (f.second < 0) | |
{ | |
stringStream << "- "; | |
} | |
else if (f.second > 0 && !isFirst) | |
{ | |
stringStream << "+ "; | |
} | |
// display scale | |
if (std::fabs(f.second) != 1 || f.first == 0) | |
{ | |
stringStream << std::fabs(f.second); | |
} | |
// display variable | |
if (f.first != 0) | |
{ | |
stringStream << variableName_; | |
if (f.first != 1) | |
{ | |
stringStream << "^" << f.first; | |
} | |
} | |
isFirst = false; | |
} | |
return stringStream.str(); | |
} | |
void Polynomial::deserialize(std::istream &stream) | |
{ | |
poly_.clear(); | |
size_t mapSize = 0; | |
Exponent exponent = 0; | |
Scale scale = 0; | |
stream.read(reinterpret_cast<char*>(&mapSize), sizeof(mapSize)); | |
for (auto i = 0; i < mapSize; ++i) | |
{ | |
stream.read(reinterpret_cast<char*>(&exponent), sizeof(exponent)); | |
stream.read(reinterpret_cast<char*>(&scale), sizeof(scale)); | |
poly_[exponent] = scale; | |
} | |
} | |
void Polynomial::serialize(std::ostream &stream) const | |
{ | |
size_t mapSize = poly_.size(); | |
stream.write(reinterpret_cast<char*>(&mapSize), sizeof(mapSize)); | |
for (const auto& f : poly_) | |
{ | |
stream.write(reinterpret_cast<const char*>(&(f.first)), sizeof(f.first)); | |
stream.write(reinterpret_cast<const char*>(&(f.second)), sizeof(f.second)); | |
} | |
} | |
Real Polynomial::operator()(Real arg) const | |
{ | |
Real acc(0); | |
for (const auto& f : poly_) | |
{ | |
acc += std::pow(arg * f.second, f.first); | |
} | |
return acc; | |
} | |
Polynomial::ScaleHandle Polynomial::operator()(size_t first, size_t last) | |
{ | |
return Polynomial::ScaleHandle(*this, first, last); | |
} | |
Polynomial Polynomial::operator*(Real rhs) const | |
{ | |
Polynomial poly(*this); | |
for (const auto& f : poly_) | |
{ | |
poly[f.first] *= rhs; | |
} | |
return poly; | |
} | |
Polynomial Polynomial::operator+(const Polynomial& rhs) const | |
{ | |
Polynomial poly(*this); | |
for (const auto& f : rhs.poly_) | |
{ | |
poly[f.first] += f.second; | |
} | |
return poly; | |
} | |
Polynomial Polynomial::operator/(Real rhs) const | |
{ | |
return (*this) * (1 / rhs); | |
} | |
Polynomial Polynomial::operator*(const Polynomial &rhs) const | |
{ | |
Polynomial poly; | |
poly.setVariableName(variableName_); | |
for (const auto& f1 : poly_) | |
{ | |
for (const auto& f2 : rhs.poly_) | |
{ | |
poly[f1.first + f2.first] += f1.second * f2.second; | |
} | |
} | |
return poly; | |
} | |
Polynomial Polynomial::operator^(Exponent rhs) const | |
{ | |
Polynomial poly(*this); | |
for (Exponent i = 1; i < rhs; ++i) | |
{ | |
poly = poly * (*this); | |
} | |
return poly; | |
} | |
std::ostream& operator<<(std::ostream &stream, const Polynomial& poly) | |
{ | |
poly.serialize(stream); | |
return stream; | |
} | |
std::istream& operator>>(std::istream &stream, Polynomial& poly) | |
{ | |
poly.deserialize(stream); | |
return stream; | |
} | |
void Polynomial::setVariableName(const std::string& variableName) | |
{ | |
variableName_ = variableName; | |
} | |
// Pseudo-variable implementation | |
Polynomial::ScaleHandle::ScaleHandle(Polynomial &parent, size_t first, size_t last) : | |
parent_(parent), first_(first), last_(last) {} | |
Polynomial::ScaleHandle::ScaleHandle(const Polynomial::ScaleHandle& rhs) : | |
parent_(rhs.parent_), first_(rhs.first_), last_(rhs.last_) {} | |
Polynomial::ScaleHandle &Polynomial::ScaleHandle::operator=(Real scale) | |
{ | |
for (auto i = first_; i <= last_; ++i) | |
{ | |
parent_[i] = scale; | |
} | |
return *this; | |
} |
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
#pragma once | |
#include <map> | |
#include <functional> | |
namespace Calculus | |
{ | |
typedef float Real; | |
struct PowerFunction | |
{ | |
Real scale; | |
Real exponent; | |
}; | |
class Polynomial | |
{ | |
public: | |
typedef size_t Exponent; | |
typedef Real Scale; | |
typedef std::map<Exponent, Scale, std::greater<Exponent>> PolynomialMap; | |
public: | |
class ScaleHandle | |
{ | |
public: | |
ScaleHandle(Polynomial& parent, Exponent first, Exponent last); | |
ScaleHandle(const ScaleHandle& rhs); | |
ScaleHandle& operator=(const ScaleHandle&) = delete; | |
ScaleHandle& operator=(Real scale); | |
private: | |
Polynomial& parent_; | |
Exponent first_; | |
Exponent last_; | |
}; | |
public: | |
Polynomial(); | |
explicit Polynomial(std::istream& stream); | |
explicit Polynomial(const PolynomialMap& polyMap); | |
Polynomial(const Polynomial& poly); | |
Polynomial& operator =(const Polynomial& rhs); | |
Scale& operator[](Exponent order); | |
PolynomialMap& operator->(); | |
std::string toString() const; | |
void deserialize(std::istream& stream); | |
void serialize(std::ostream& stream) const; | |
Real operator()(Real arg) const; | |
ScaleHandle operator()(Exponent first, Exponent last); | |
Polynomial operator*(Real rhs) const; | |
Polynomial operator/(Real rhs) const; | |
Polynomial operator^(Exponent rhs) const; | |
Polynomial operator*(const Polynomial& rhs) const; | |
Polynomial operator+(const Polynomial& rhs) const; | |
void setVariableName(const std::string& variableName); | |
private: | |
PolynomialMap poly_; | |
std::string variableName_; | |
}; | |
} | |
std::ostream& operator<<(std::ostream& stream, const Calculus::Polynomial& poly); | |
std::istream& operator>>(std::istream& stream, Calculus::Polynomial& poly); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment