A Scala implementation of Newton’s Method for solving equations

During some quiet time recently, I decided to exercise my brain a little bit, and wrote a Scala implementation of Newton's Method for solving equations. In the Scala class/object below, I define two functions, f(x) and f'(x), and then solve those equations using my implementation of Newton's Method.

Note: I wrote the following code several years before I wrote the Scala Cookbook, so it’s a little sloppy, and it’s not written in a pure “functional programming” (FP) style. I’ll update it to a Pure-FP style when I have a little more free time.

I could clean up the source code a little bit, but in short, the newtonsMethod function is the main "solver" function, while the newtonsMethodHelper function does what it's documentation says, implementing the calculation shown.

object NewtonsMethod {

  def main(args: Array[String]) {
    driver
  }
  
  /**
   * A "driver" function to test Newton's method.
   * Start with (a) the desired f(x) and f'(x) equations,
   * (b) an initial guess and (c) tolerance values. 
   */
  def driver {
    
    // i pulled these f(x) and f'(x) functions from my old
    // Applied Numerical Analysis book
    
    // the f(x) and f'(x) functions
    val fx = (x: Double) => 3*x + Math.sin(x) - scala.math.pow(Math.E, x)
    val fxPrime = (x: Double) => 3 + Math.cos(x) - scala.math.pow(Math.E, x)

    val initialGuess = 0.0
    val tolerance = 0.00005
    
    // pass f(x) and f'(x) to the Newton's Method function, along with the initial guess
    // and tolerance
    val answer = newtonsMethod(fx, fxPrime, initialGuess, tolerance)

    println(answer)
  }

  /**
   * Newton's Method for solving equations.
   * TODO: check that |f(xNext)| is greater than a second tolerance value
   * TODO: check that f'(x) != 0
   */
  def newtonsMethod(fx: Double => Double, 
                    fxPrime: Double => Double,
                    x: Double,
                    tolerance: Double): Double = {
    var x1 = x
    var xNext = newtonsMethodHelper(fx, fxPrime, x1)
    while (Math.abs(xNext - x1) > tolerance) {
      x1 = xNext
      println(xNext) // debugging (intermediate values)
      xNext = newtonsMethodHelper(fx, fxPrime, x1)
    }
    
    return xNext
  }

  /**
   * This is the "x2 = x1 - f(x1)/f'(x1)" calculation 
   */
  def newtonsMethodHelper(fx: Double => Double, 
                          fxPrime: Double => Double,
                          x: Double): Double = {
    return x - fx(x) / fxPrime(x)
  }

}

As you can see from the code, I use the scala.math.pow function several times. I explain the need for this in my Scala power exponentiation tutorial.

I enjoy writing code like this for several reasons. First, I love math. Second, it lets me explore features of Scala that I don't always get to use, in this case passing functions around between other functions.

There are a couple of features of Newton’s Method that I haven't implemented yet (due to time constraints), and I’ll implement those some time in the future, maybe during a ScalaTest tutorial.

I should also note that the code I wrote is not based on the Wikipedia entry for Newton's Method. I didn't look at that page until just now. I wrote my code based on an old book named Applied Numerical Analysis (first published in 1970, wow).

Finally, I want to note that the style of code here is a combination of OOP (object-oriented programming) and FP (functional programming). At some point I hope to have the time to rewrite it in a completely FP style.