#include #include #include using namespace std; class Function : public unary_function { public: Function() {}; virtual result_type operator()(argument_type x){return x;}; virtual Function& getDerivative() { return *this;}; }; class ProtonNeutronFunc : public Function { public: ProtonNeutronFunc(double factor, double exponent_factor, double angular, double energy) :k(factor), a(exponent_factor), m(angular), E(energy), d(factor,exponent_factor,angular) {}; virtual result_type operator()(argument_type x) { return -1*k*exp(-1*x/a) + m/pow(x,2) - E; }; virtual Function& getDerivative() { return d; }; protected: double k; double a; double m; double E; class ProtonNeutronDerivativeFunc : public Function { public: ProtonNeutronDerivativeFunc(double _k, double _a, double _m) : k(_k),a(_a),m(_m), d(_k,_a,_m) {}; result_type operator () (argument_type x) { return (k/a)*exp(-1*x/a) - m*2/pow(x,3); }; Function& getDerivative() { return d; }; protected: class PNddFunc: public Function { public: PNddFunc(double _k, double _a, double _m) : k(_k),a(_a),m(_m) {}; result_type operator () (argument_type x) { return m*6/pow(x,4) - (k/pow(a,2))*exp(-1*x/a); }; protected: double k; double a; double m; }; protected: double k; double a; double m; PNddFunc d; }; ProtonNeutronDerivativeFunc d; }; class Approximation { public: Approximation(double lowerBound, double upperBound, Function& function) :a(lowerBound), b(upperBound), f(function) {}; virtual double calculate(double precision, int maxTries = 3000) { cout << "Default approximation not implemented" << endl; return -1; } protected: double a; double b; Function& f; }; class NewtonApproximation : public Approximation { public: NewtonApproximation(double lower, double upper, Function& f, Function& derivative) :Approximation(lower,upper,f), d(derivative) {}; double calculate(double precision=0.0, int maxTries=3000) { double x0 = (a+b)/2; double xn; double p = b-a; while ((p > precision) && (--maxTries)) { //cout << "x=" << x0 << "\tf=" << f(x0) <<"\td=" << d(x0) << endl; xn = x0 - f(x0)/d(x0); if (xn>b) xn = (x0+b)/2; if (xn