import RootComputer;
import RootTester;
import SimpleOutput;

/**
 * Compute the square root of a value supplied on the command
 * line.  
 * Usage:
 *   java IterativeRoot value tolerance
 * If you'd like to know what steps it goes through, supply
 * an initial guess, too.
 *   java IterativeRoot value tolerance guess
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of October 1999
 */
public class IterativeRoot 
  implements RootComputer
{

  // +---------+-------------------------------------------------
  // | Methods |
  // +---------+

  /**
   * Compute the square root of num to within a specified tolerance, 
   * using estimate guess as the current estimate.  Uses Newton's
   * method for approximation.  If observer is non-null, prints out
   * information at each step.
   */
  public double sqrt(double num, double guess, double tolerance,
                     SimpleOutput observer) {
    if (observer != null) {
      observer.println("N: " + num 
                       + "; T: " + tolerance);
    }
    while (Math.abs(guess*guess-num)  >= tolerance) {
      if (observer != null) 
        observer.println("  A: " + guess);
      guess = (num + guess*guess) / (2*guess);
    }
    observer.println("Final estimate: " + guess);
    return guess;
  } // sqrt(num,num,num,SimpleOutput)

  // +------+----------------------------------------------------
  // | Main |
  // +------+

  public static void main(String[] args) {
    // Prepare for output.
    SimpleOutput out = new SimpleOutput();
    // Create something for testing.
    RootTester tester = new RootTester();
    // And test
    if (!tester.test(args, new IterativeRoot(), out)) {
      out.println("Usage: java IterativeRoot num tolerance");
      out.println("   Or: java IterativeRoot num tolerance firstguess");
    }
  } // main(String[])
} // class IterativeRoot

