Yes. Since lambdas behave just like functors, and you are using template parameters, it will be fine.
Updated with lambda functions and boost::lexical_cast. I also decided to go with fp for the derivative name instead of fPrime, and that x is a less arbitrary initial guess than x / 2.
Code:#include <cassert> #include <cmath> #include <cstdlib> #include <iostream> #include "boost/cstdint.hpp" #include "boost/lexical_cast.hpp" template <typename Function1, typename Function2> double NewtonsMethod( Function1 f, Function2 fp, 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) / fp(x); ++iterations; } while (std::abs(x - last) > tolerance && iterations != maxIterations); return x; } 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 = boost::lexical_cast<boost::uint32_t>(argv[1]); x = boost::lexical_cast<double>(argv[2]); double nthRootOfX = NewtonsMethod( [n, x] (double v) -> double { return std::pow(v, n) - x; }, // f [n, x] (double v) -> double { return n * std::pow(v, n - 1); }, // f' x, // x[0] 10E-6, // tolerance 100); // max iterations std::cout << nthRootOfX << std::endl; return 0; }
Ha, every solution brings another problem :-P. I don't know quite what it is about exception handling, but I'm resistant to doing it. I guess I'm more concerned with how my code looks than how the program it produces looks! Maybe I should think twice about those feelings. Here's the new code:
Code:#include <cassert> #include <cmath> #include <cstdlib> #include <iostream> #include "boost/cstdint.hpp" #include "boost/lexical_cast.hpp" template <typename Function1, typename Function2> double NewtonsMethod( Function1 f, Function2 fp, 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) / fp(x); ++iterations; } while (std::abs(x - last) > tolerance && iterations != maxIterations); return x; } void UsageErrorMessage(const char* programName) { std::cerr << "Usage: " << programName << " n x" << std::endl; std::cerr << "(Prints the nth root of x)" << std::endl; } int main(int argc, char** argv) { if (argc != 3) { UsageErrorMessage(argv[0]); return 1; } boost::uint32_t n; double x; try { n = boost::lexical_cast<boost::uint32_t>(argv[1]); x = boost::lexical_cast<double>(argv[2]); } catch (boost::bad_lexical_cast) { std::cerr << "Error: Could not convert arguments to numbers" << std::endl; UsageErrorMessage(argv[0]); return 1; } double nthRootOfX = NewtonsMethod( [n, x] (double v) -> double { return std::pow(v, n) - x; }, // f [n, x] (double v) -> double { return n * std::pow(v, n - 1); }, // f' x, // x[0] 10E-6, // tolerance 100); // max iterations std::cout << nthRootOfX << std::endl; return 0; }