Thread: Newton's Method

  1. #31
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes. Since lambdas behave just like functors, and you are using template parameters, it will be fine.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #32
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    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;
    }

  3. #33
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Looks nice. The only complaint is that lexical_cast throws if it fails. You should probably intercept this and display an error.
    Are you sure the derivative is right, though? Looks like you've missed a "-1".
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #34
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    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;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newton's Method for Systems of Nonlinear Equations
    By Delia in forum C Programming
    Replies: 1
    Last Post: 11-10-2010, 07:17 PM
  2. Packet Container Class
    By ChaoticXSinZ in forum C++ Programming
    Replies: 2
    Last Post: 11-01-2010, 12:07 AM
  3. on method pointers and inheritance
    By BrownB in forum C++ Programming
    Replies: 2
    Last Post: 03-02-2009, 07:50 PM
  4. Cubic Root by Newton's Iterative Method
    By amirahasanen1 in forum C++ Programming
    Replies: 2
    Last Post: 03-15-2005, 02:05 PM
  5. Newton's method
    By Cmuppet in forum C Programming
    Replies: 5
    Last Post: 10-19-2004, 11:02 AM

Tags for this Thread