Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Newton's method, due to Isaac Newton (1642-1726) is a procedure to find zero-crossings of a function f. The procedure needs an initial guess for x,

Newton's method, due to Isaac Newton (1642-1726) is a procedure to find zero-crossings of a function f. The procedure needs an initial guess for x, which is uses iteratively to find a new x such that f(x)=0. Because of numerical imprecision and floating point errors, the procedure might not terminate with f(x)=0, so many implementations of the procedure stop after a limited number of iterations or when the absolute value of f(x) is smaller than some small value epsilon.

Part of Newton's method needs to use the derivative of f; a common use of Newton's method is to find roots of a polynomial because the derivative is easy to compute exactly.

Here is the Double types:

import kotlin.math.absoluteValue // EPSILON is how "close" two numbers need to be // to be considered approximately equal for the Newton // algorithm; LIMIT is a maximum number of iterations // of the Newton algorithm before it gives up val EPSILON = 1.0e-10 val LIMIT = 50 // LimitError is a custom Java error just for Newton class LimitError: Error() /*************************************************************************** * The Newton-Raphson (see https://en.wikipedia.org/wiki/Newton%27s_method) * * algorithm searches for the root of a function f(x), where "root" means a * * value for x such that f(x)=0. Here, we only consider polynomial f(x) * * Example: f(x) = (3x-2)*(-4x+3) = -12x^2 + 17x - 6 * * has coefficients [-12, 17, -6] and the roots are 2/3 and 3/4 * * The solve() method of the Newton class has two inputs, an array for * * the coefficients and an initial "guess" for a root's value; solve() * * will either return a root or throw a LimitError. * ***************************************************************************/ class Newton { // solve() needs the polynomial coefficients and an initial guess  // for the value of a root of the polynomial; try different guess  // values to discover different roots of the polynomial  fun solve(coef: Array, guess: Double): Double { // func() evaluates and returns the polynomial for  // a given input value; it is a local function to Newton  fun func(p: Array, value: Double): Double { var result: Double = 0.0 var powerd: Double = 1.0 for (c in p.reversedArray()) { result += c * powerd powerd *= value } // println("coef=${p.toList()},guess=$guess,result=$result")  return result } // deriv() evaluates the first derivative of the input  // polynomial at a given input value  fun deriv(p: Array, value: Double): Double { val prime = Array(p.size - 1, { i -> (p.size - 1 - i).toDouble() * p[i] }) return func(prime, value) } var x = guess var t = func(coef, x) / deriv(coef, x) var loopcount = 0 while (t.absoluteValue >= EPSILON) { // println("x=$x func(x)=${func(coef,x)}")  t = func(coef, x) / deriv(coef, x) x = x - t loopcount++ if (loopcount > LIMIT) throw LimitError() } return x } } fun main(args: Array) { // for deugging, run main and test Newton().solve()  val coef = arrayOf(1.0,0.0,-9.0) val T = Newton().solve(coef,1.5) println(T) // should print 3.0  }

The homework asks you to take the working procedure for Double types and replace all uses of Double with a new type, Complex, that you define. Here are some things to know about the Complex type.

Each instance of Complex has two properties, real and imaginary (each is a Double value)

The traditional mathematical notation for a complex number is a+bi, where a is the real part an b is the imaginary part, and i is the square root of -1 (most tutorials use this notation to explain operations)

Operations of plus, minus, times, and div are defined for complex numbers:

(a+bi) + (c+di) = (a+c) + (b+d)i

(a+bi) - (c+di) = (a-c) + (b-d)i

(a+bi) * (c+di) = (ac-bd) + (ad+bc)i

The reciprocal of a complex number (a+bi) is

1/(a+bi) = (a/s) - (b/s)i where s = a*a + b*b

To do division of two complex numbers t and w, simply calculate t*(1/w)

All of the basic operations plus, minus, times and div should be infix functions (methods) of the Complex class.

In addition, Complex also needs an absoluteValue property. The absolute value of (a+bi) is defined as sqrt(a*a + b*b)

Code in Kotlin

Complete the following code to pass the Test code

import kotlin.math.absoluteValue val EPSILON = 1.0e-10 val LIMIT = 50 class LimitError: Error() // documentation is found in the newton project (this is newtoncomplex) // the solve() method is the same as in newton, except that the new // Complex type of number is used instead of Double class NewtonComplex { fun solve(coef: Array, guess: Complex): Complex { fun func(p: Array, value: Complex): Complex { var result: Complex = Complex(0.0,0.0) var powerd: Complex = Complex(1.0,0.0) for (c in p.reversedArray()) { result += c * powerd powerd *= value } // println("coef=${p.toList()},guess=$guess,result=$result")  return result } fun deriv(p: Array, value: Complex): Complex { val prime = Array(p.size - 1, { i -> Complex((p.size - 1 - i).toDouble(),0.0) * Complex(p[i].real,p[i].imaginary) }) return func(prime, value) } var x = guess var t = func(coef, x) / deriv(coef, x) var loopcount = 0 while (t.absoluteValue >= EPSILON) { // println("x=$x func(x)=${func(coef,x)}")  t = func(coef, x) / deriv(coef, x) // println("** $t ** ${t.absoluteValue}")  x = x - t loopcount++ if (loopcount > LIMIT) throw LimitError() } return x } } fun main(args: Array) { // debugging test, just for equation x^2 + 1 = 0, ie x^2 = -1  val coef = arrayOf( Complex(1.0,0.0), Complex(0.0,0.0), Complex(1.0,0.0)) val soln = NewtonComplex().solve(coef,Complex(2.0,2.0)) println("Root = $soln") // should be 0.0+1.0i approximately  }

Test Code:

import org.junit.Assert.* import org.junit.Test class NewtonComplexTest { @Test fun test1() { // test of x^2 + 9 = 0  val solver = NewtonComplex() val coef = arrayOf( Complex(1.0,0.0), Complex(0.0,0.0), Complex(9.0,0.0)) var soln = solver.solve(coef,Complex(2.0,0.01)) var dist = (soln - Complex(0.0,3.0)).absoluteValue  assertTrue( dist <= EPSILON ) // test that 3i is the solution  } @Test fun test2() { // test of x^2 + (1-i)x + (2-2i) = 0  val solver = NewtonComplex() var coef = arrayOf( Complex(1.0,0.0), Complex(1.0,-1.0), Complex(2.0,-2.0)) var soln = solver.solve(coef,Complex(1.0,1.0)) // println(soln)  var dist = (soln - Complex(0.0,2.0)).absoluteValue  assertTrue( dist <= EPSILON) // 0+2i is one root  soln = solver.solve(coef,Complex(2.0,-3.0)) // println(soln)  dist = (soln - Complex(-1.0,-1.0)).absoluteValue  assertTrue( dist <= EPSILON ) // -1-1i is another root  } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Intelligent Information And Database Systems Third International Conference Achids 2011 Daegu Korea April 2011 Proceedings Part 2 Lnai 6592

Authors: Ngoc Thanh Nguyen ,Chong-Gun Kim ,Adam Janiak

2011th Edition

3642200419, 978-3642200410

Students also viewed these Databases questions