/** * Immutable class for a quadratic equation * * @author P. Conrad * @version 04/06/2009 */ public class QuadraticEqn { private double a; private double b; private double c; /** * Constructor for objects of class QuadraticEqn */ public QuadraticEqn(double a, double b, double c) { this.a = a; this.b = b; this.c = c; } /** * get the value of a * * @return the value of the a coefficient */ public double getA() { return a; } /** * get the value of b * @return the value of the b coefficient */ public double getB() { return b; } /** * get the value of c * @return the value of the c coefficient */ public double getC() { return c; } /** Calculate the number of real roots * @return the number of real roots, either 0, 1 or 2. */ public int numRealRoots() { if (hasDegenerateRoot()) return 1; if (a==0) { assert b==0; // it must be because hasDegenerateRoot failed return 0; // we can't calculate a solution when a==0 and b==0 } // now we just use the discriminant double disc = this.calcDiscriminant(); if (disc > 0) { return 2; } else if (disc < 0) { return 0; } else { return 1; } } /** Calculate the discriminant * * @return the discriminant */ public double calcDiscriminant() { return b*b-(4.0*a*c); } /** Predicate function: has dengerate root. For purposes of this problem: True when a==0 and b!=0 * * (Note: there are other definitions of degnerate root, but that is the one we are using) * * @return True if a==0 and b!=0 */ public boolean hasDegenerateRoot() { return (a==0 && b!= 0); } /** Predicate function: has dengerate root. For purposes of this problem: True when a==0 and b!=0 * * (Note: there are other definitions of degnerate root, but that is the one we are using) * * @return True if a==0 and b!=0 */ public double degenerateRoot() { if (!hasDegenerateRoot()) throw new RuntimeException("degenerateRoot() callled when QuadraticEqn object has no dengenerate root"); return ( -c / b); } /** Return the first real root (the one with + in the quadratic formula) * If there are no real roots, raise an exception. If there is a single degenerate root, return it. * * @return the value of the first real root */ public double realRoot1() { // Note how "else" is not needed because "throw" and return end the function call if (numRealRoots() < 1) throw new RuntimeException("realRoot1() called on QuadraticEqn object with no real roots"); if (hasDegenerateRoot()) return degenerateRoot(); return (-b + Math.sqrt(calcDiscriminant()) / (2.0 * a)); } /** Return the second real root (the one with - in the quadratic formula) * If there are no real roots, raise an exception * * @return the value of the second real root */ public double realRoot2() { // Note how "else" is not needed because "throw" and return end the function call if (numRealRoots() < 1) throw new RuntimeException("realRoot1() called on QuadraticEqn object with no real roots"); if (hasDegenerateRoot()) return degenerateRoot(); return (-b - Math.sqrt(calcDiscriminant()) / (2.0 * a)); } /** Return the first Complex root (the one with + in the quadratic formula) * If there are no Complex roots, raise an exception. If there is a single degenerate root, return it. * * If the first root is real, return it as a Complex number with the real part being the * real root, and the imaginary part as zero. * * Otherwise, return the root as a Complex number. * * @return the value of the first Complex root */ public Complex complexRoot1() { // Note how "else" is not needed because "throw" and "return" both end the function call if (hasDegenerateRoot()) return new Complex(degenerateRoot(), 0.0); if (a==0) { assert b==0; throw new RuntimeException("Cannot calculate Complex roots when a==0 and b==0"); } double disc = calcDiscriminant(); // if its positive, return a Complex with no imaginary part if (disc > 0) return new Complex ( realRoot1(), 0.0); // otherwise, calculate the coefficients of a + bi return new Complex ( ( -b / 2.0 * a ), ( Math.sqrt(-disc) / 2.0 * a)); } /** Return the first Complex root (the one with - in the quadratic formula) * If there are no Complex roots, raise an exception. If there is a single degenerate root, return it. * * If the first root is real, return it as a Complex number with the real part being the * real root, and the imaginary part as zero. * * Otherwise, return the root as a Complex number. * * @return the value of the first Complex root */ public Complex complexRoot2() { // @@@ IMPLEMENT THIS METHOD (following the example of complexRoot1 return new Complex(); // @@@ stub! remove! } /** Evaluate quadratic equation for a real (double) value of x. This lets us test whether a root really * gives us 0 or not. * * @param x The value of x to be evalauted * @return The value of ax^2 + bx + c */ public double evaluate(double x) { return -99; // @@@ STUB! fix code and remove !!! } /** Evaluate quadratic equation for a Complex value of x. This lets us test whether a complex root really * gives us 0 or not. * * @param x The value of x to be evalauted * @return The value of ax^2 + bx + c */ public Complex evaluate(Complex x) { // @@@ FINISH THIS METHOD... I've given you a start // The goal is to compute a*x*x + b*x + c, just like // with the double version of evaluate--but this time all the multiplications and additions // have to be done with function calls to the static methods of the Complex class, // multiply and add // first, convert a, b and c to complex versions //Complex a_ = new Complex(this.a, 0.0); //Complex b_ = ___________________; //Complex c_ = ___________________; // @@@ Now compute the first term, the a * x * x, but use the multiply function of the Complex class. // Remember to use a_ (the complex version of a), not the instance variable (which is of type double), // so that you can use multiply (which requires two Complex parameters.) // // Hint: your answer may involving nesting one function call inside another, // i.e. something of the form answer = foo.bar ( x, foo.bar ( x, y) ) // Complex firstTerm = ________________________ // @@@ Now compute the second term, b * x in the same way, // Complex secondTerm = ____________________ // Now you can add the firstTerm, the secondTerm and the value of c together, and return // that as the answer, an answer of type Complex // return ______________________ return new Complex(-49.0, 42.0); // @@@ stub! remove! } }