Paul Heidmann Fractal Example  1.0
newtonsMethod.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // Copyright (C) 2014 Paul S. Heidmann
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // For a copy of the GNU General Public License see
16 // <http://www.gnu.org/licenses/>.
17 //
18 // Author contact info:
19 // Paul Heidmann
20 // paul@heidmann.com
21 
22 #include <complex>
23 #include <cstdint>
24 #include <stdexcept>
25 #include <functional>
26 
27 namespace fractal
28 {
29 
30 /// \brief This class implements Newton's method (the same one from
31 /// your typical first year calculus class), to find zeros
32 /// of complex valued functions (in the complex plain,
33 /// obviously).
34 /// \tparam floatType The floating point type to be used in the
35 /// underlying computations.
36 /// \author Paul S. Heidmann
37 template<typename floatType>
39 {
40 public:
41 
42  /// \brief This type is used to declare variables that hold
43  /// complex numbers.
44  typedef std::complex<floatType> cmplxType;
45 
46  /// \brief This type is used to declare variables that hold
47  /// functions whose zeros are being found.
48  typedef std::function<cmplxType(const cmplxType&)> funcType;
49 
50  newtonsMethod() = delete;
51 
52  /// \brief This is the constructor that must be used to create
53  /// instances of this class.
54  /// \param initialGuess The complex number that is to serve as
55  /// the initial guess of the zero to be found.
56  /// \param f The function whose zero is to be found.
57  /// \param f_prime The derivative of the function whose zero is
58  /// to be found.
59  /// \param maxIterations The maximum number of iterations that may
60  /// be used by this implementation to find a zero.
61  /// \param epsilon The required accuracy. The zero must be found
62  /// within this tolerance.
64  const cmplxType& initialGuess,
65  const funcType& f,
66  const funcType& f_prime,
67  const std::uint32_t maxIterations,
68  const floatType& epsilon ) :
69  m_initialGuess{ initialGuess },
70  m_f{ f },
71  m_fPrime{ f_prime },
72  m_maxIterations{ maxIterations },
73  m_epsilon{ epsilon }
74  {
75  }
76 
77  /// \brief The class destructor.
79 
80  /// \brief This method is called to find a zero of the given function,
81  /// using the given initial guess.
82  /// \param numIters An output parameter. The number of iterations actually
83  /// required to find the given zero.
84  /// \return The zero found.
85  const cmplxType findZero( std::uint32_t& numIters ) const
86  {
87  numIters = 0;
88  if( (this->m_epsilon) < 0.0 )
89  throw std::runtime_error( "Epsilon must be greater than zero!" );
90 
91  cmplxType curGuess( this->m_initialGuess );
92  while( numIters < (this->m_maxIterations) )
93  {
94  const cmplxType prevGuess{ curGuess };
95  const cmplxType numerator{ (this->m_f)(curGuess) };
96  const cmplxType denominator{ (this->m_fPrime)(curGuess) };
97  if( denominator == 0.0 )
98  throw std::runtime_error( "Zero denominator in newtons method!" );
99  curGuess -= (numerator / denominator);
100  const floatType curEpsilon{ std::abs( curGuess - prevGuess ) };
101  if( curEpsilon <= (this->m_epsilon) )
102  return( std::move( curGuess ) );
103  ++numIters;
104  }
105  throw std::runtime_error( "Newton's method not converging!" );
106  }
107 
108 private:
109 
110  /// \brief This attribute holds the caller supplied initial guess.
112 
113  /// \brief This attribute holds the function whose zero is to be found.
114  const funcType m_f;
115 
116  /// \brief This attribute holds the derivative of the function whose
117  /// zero is to be found.
119 
120  /// \brief This attribute holds the maximum number of iterations allowed
121  /// when searching for a zero.
122  const std::uint32_t m_maxIterations;
123 
124  /// \brief This attribute holds the required accuracy (that is, tolerance).
125  const floatType m_epsilon;
126 };
127 
128 }
const floatType m_epsilon
This attribute holds the required accuracy (that is, tolerance).
~newtonsMethod()
The class destructor.
std::function< cmplxType(const cmplxType &)> funcType
This type is used to declare variables that hold functions whose zeros are being found.
std::complex< floatType > cmplxType
This type is used to declare variables that hold complex numbers.
newtonsMethod(const cmplxType &initialGuess, const funcType &f, const funcType &f_prime, const std::uint32_t maxIterations, const floatType &epsilon)
This is the constructor that must be used to create instances of this class.
const cmplxType m_initialGuess
This attribute holds the caller supplied initial guess.
const funcType m_fPrime
This attribute holds the derivative of the function whose zero is to be found.
This class implements Newton&#39;s method (the same one from your typical first year calculus class)...
const cmplxType findZero(std::uint32_t &numIters) const
This method is called to find a zero of the given function, using the given initial guess...
const std::uint32_t m_maxIterations
This attribute holds the maximum number of iterations allowed when searching for a zero...
const funcType m_f
This attribute holds the function whose zero is to be found.