Answer for Assignment 4
Below is the graph of the orbit of the conservative central force problem where U(r)=-ke^-r/a. These paths were plotted using a Simpson numerical integral approximation to evaluate theta by performing a preservation of angular momentum derived formula giving an equation for theta in terms of an integral from an initial radius to the radius for which one wishes to determine theta.

#include <functional> #include <iostream> #include <math.h>
using namespace std;
const double pi = acos(-1);
class Function : public unary_function<double,double>
{
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)
{};
virtual result_type operator()(argument_type x)
{
return -1*k*exp(-1*x/a) + m/pow(x,2) - E;
};
protected: double k; double a; double m; double E;
};
class ThetaOfR : public ProtonNeutronFunc
{
public:
ThetaOfR(double factor, double exponent_factor, double angular, double energy)
: ProtonNeutronFunc(factor, exponent_factor, angular, energy)
{};
virtual result_type operator()(argument_type x)
{
return 2*m / ((x*x)*sqrt(4*m*( 0-ProtonNeutronFunc::operator ()(x) ) ) );
};
};
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 SimpsonsApproximation : public Approximation
{
public:
SimpsonsApproximation(double lowerBound, double upperBound, Function & function)
: Approximation(lowerBound, upperBound,function)
{
if (a >=b) cerr << "Lowerbound " << a << " is greater than or equal to upper bound " << b << endl;
};
virtual double calculate(double precision, int maxTries=50)
{
double i, sum0;
double h = (b-a)/3;
double se= f(a+2*h), so = f(a+h) + f(b-h), sd = f(a) + f(b);
double sum = h*(sd + 2*se + 4*so)/3;
if (h <= 0) return 0;
do
{
h/=2;
sum0 = sum;
se+=so;
so =0;
for (i = a+h; i < b; i+=2*h)
so+=f(i);
sum = h*(sd + 2*se +4*so)/3;
//cout << sd << "\t" << se << "\t" << so << "\t" << sum << endl;
} while ((fabs((sum - sum0)/sum0) > precision) && (maxTries--));
return sum;
}
};
int main(int argc, char* argv[])
{
ThetaOfR func25(70, 0.2, 0.01, 25);
ThetaOfR funcneg25(70, 0.2, 0.01, -25);
double r = 0, rmin=0.010458; double theta, thetaN;
cout.precision(16); cout << "# Welcome to the Simpson numerical integral approximation program for the Neutron-Proton Derivative" << endl; cout << "# for E=25 theta(r) = " << endl;
SimpsonsApproximation total25(rmin, 1, func25); thetaN=total25.calculate(0.0001);
for (r=1;r >=rmin;r-=0.001)//*log(r/rmin))
{
SimpsonsApproximation sp(r, 1, func25);
theta = sp.calculate(0.00001);
cout << r*cos(theta) << "\t" << r*sin(theta) <<endl;
cout << r*cos(2*thetaN - theta) << "\t" << r*sin(2*thetaN - theta) << endl;
}
cout << endl << "# for E=-25" << endl;
SimpsonsApproximation totalneg25(0.0158798, 0.204010, funcneg25); thetaN=totalneg25.calculate(0.00001);
for (r=0.0158798;r <= 0.204011;r+=0.0002)
{
SimpsonsApproximation sp(0.0158797, r, funcneg25);
//cout << r << "\t" << funcneg25(r) << endl;
theta = sp.calculate(0.00001);
for (int i =0;i<18;i+=2)
{
cout << r*cos(i*thetaN + theta) << "\t" << r*sin(i*thetaN + theta) <<endl;
cout << r*cos((i+2)*thetaN-theta) << "\t" << r*sin((i+2)*thetaN-theta) << endl;
}
}
return 0; }
GNUplot script file: