For a bit of fun, I thought I'd write my version of this program. Criticisms encouraged :-).
Code:
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include "boost/bind.hpp"
#include "boost/cstdint.hpp"
template <typename Function1, typename Function2>
double NewtonsMethod(
Function1 f,
Function2 fPrime,
double x,
double tolerance,
boost::uint32_t maxIterations)
{
assert(tolerance > 0);
assert(maxIterations != 0);
double last;
boost::uint32_t iterations = 0;
do
{
last = x;
x -= f(x) / fPrime(x);
++iterations;
}
while (std::abs(x - last) > tolerance && iterations != maxIterations);
return x;
}
double XPowNMinusC(double x, boost::uint32_t n, double c) { return std::pow(x, n) - c; }
double XPowNMinusCPrime(double x, boost::uint32_t n, double c) { return n * std::pow(x, n - 1); }
int main(int argc, char** argv)
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " n x" << std::endl;
std::cerr << "(Prints the nth root of x)" << std::endl;
return 1;
}
boost::uint32_t n;
double x;
n = atoi(argv[1]);
x = atof(argv[2]);
double nthRootOfX = NewtonsMethod(
boost::bind(XPowNMinusC, _1, n, x), // f
boost::bind(XPowNMinusCPrime, _1, n, x), // f'
x / 2, // x[0]
10E-6, // tolerance
100); // max iterations
std::cout << nthRootOfX << std::endl;
return 0;
}