CMPS 144 Fall 2022
Prog. Assg. #2: Polynomial
Due: Oct. 20, 11:59:59pm

Background

As anyone who completed high school math recently will remember, a polynomial is a function p(x) that can be expressed as

p(x) = c0 + c1x + c2x2 + ... + cmxm

where x is the independent variable and each of the ci's is a so-called coefficient. (In this assignment, all coefficients will be integers.) Each of the summands cixi is referred to as a term. The largest power of x among those terms with a non-zero coefficient is called the degree of the polynomial. (The absence of terms cm+1xm+1, cm+2xm+2, etc., etc., can be taken to imply that each of cm+1, cm+2, etc., etc., is zero.) For the special case of the polynomial having no nonzero coefficients, we call it the "zero polynomial" and define its degree to be zero.

For example, if we choose as coefficients c0 = 5, c1 = −3, c2 = 1, c3 = 0, and c4 = 2, we get the polynomial (of degree four)

p(x) = 5 + −3x + 1x2 + 0x3 + 2x4

By convention, when displaying a polynomial we usually omit coefficients that are 1 and any term whose coefficient is zero. Also, we use infix minus operators rather than unary ones, except in the first term. Thus, our example p(x) would more likely be written as

p(x) = 5 − 3x + x2 + 2x4

Evaluation/Application

As with any function, a polynomial can be evaluated at (or applied to, if you prefer) a specified value of x. For example, to evaluate p(x) at 2.5, we plug in 2.5 for x and carry out the prescribed multiplications and additions:
p(2.5)  =  (5)(2.50) + (−3)(2.51) + (1)(2.52) + (0)(2.53) + (2)(2.54)
   =  (5)(1) + (−3)(2.5) + (1)(6.25) + (0)(15.625) + (2)(39.0625)
   =  5 + −7.5 + 6.25 + 0 + 78.125
   =  81.875

A clever way of evaluating a polynomial —and one that is more efficient than the more obvious approach— is based on the observation that

c0 + c1x + c2x2 + ... + cmxm  =  c0 + x(c1 + x(c2 + ... + x(cm-1 + x(cm))...))

You are encouraged to apply this approach in the relevant method, but it is not a requirement.

Sum, Difference, and Product

Suppose that q(x) and r(x) are polynomials as follows:

q(x) = a0 + a1x + a2x2 + ... + amxm
r(x) = b0 + b1x + b2x2 + ... + bnxn

Without loss of generality, we assume m≤n. Then the sum of q(x) and r(x) is the polynomial

(q+r)(x) = (a0+b0) + (a1+b1)x + (a2+b2)x2 + ... + (am+bm)xm + bm+1xm+1 + ... + bnxn

That is, each coefficient of (q+r)(x) is obtained by adding the corresponding coefficients of q(x) and r(x). Notice that because m≤n, we take each of am+1, am+2, ..., an to be zero. For example, if q(x) = −3 + 2x + 8x3 and r(x) = 7 + −11x + 4x2, then

(q+r)(x)  =  (−3+7) + (2+ −11)x + (0+4)x2 + (8+0)x3  =  4 + −9x + 4x2 + 8x3

Analogously, each coefficient of the difference of q(x) and r(x), (q−r)(x), is obtained by taking the difference (ai−bi) of the corresponding coefficients of q and r. Continuing our example,

(q−r)(x)  =  (−3−7) + (2− −11)x + (0−4)x2 + (8−0)x3  =  −10 + 13x + −4x2 + 8x3

The product of q(x) and r(x), (q·r)(x), is a bit more difficult to compute. First, the degree of (q·r)(x) is m+n, the sum of the degrees of q(x) and r(x). (An exception to this occurs when either q(x) or r(x) is the zero polynomial, as then the product is the zero polynomial (which has degree zero).) For each k in the range [0 .. m+n], the coefficient of the xk-term in (q·r)(x) is

Σ0≤i≤k (ai·bk−i)   =   a0·bk + a1·bk-1 + a2·bk-2 + ... + ak·b0

Notice how the subscripts in each term add up to k.

Continuing our example, we compute the coefficient of x3 in (q·r)(x) as follows:

a0·b3 + a1·b2 + a2·b1 + a3·b0
(−3)(0) + (2)(4) + (0)(−11) + (8)(7)
0 + 8 + 0 + 56
64

Carrying out the similar calculations for the other coefficients, we find that

(q·r)(x) = −21 + 47x + −34x2 + 64x3 + −88x4 + 32x5.

Roots (Zeros) of a Polynomial

Let f(x) be a function. Then any value a such that f(a) = 0 is said to be a root (or zero) of f.

All polynomials are continuous functions, which, informally, means that each one's graph can be drawn without "lifting pencil off paper". For any continuous function f(x) and real numbers a and b with a < b, if f(a)·f(b) ≤ 0 (which is to say that either one of a or b is a root or else f(a) and f(b) have opposite signs), then there is a real number c with a ≤ c ≤ b such that c is a root of f(x).

It follows that, to search for a root in the interval [a,b], we can choose any d between a and b and then determine, based upon the value of f(a)·f(d), whether or not there is sure to be a root in the interval [a,d]. If so, continue the search there. If not, search in [d,b]. (If the term binary search has not already come to your mind, it should have!)


The Polynomial Class

For this assignment, you are to complete the Polynomial class, each instance of which represents a polynomial with integer coefficients.

Methods that need to be completed include those that carry out the operations described above. By examining the given source code, you will notice that the methods that compute the sum, difference, and product, respectively, of two polynomials are not classified as mutators but rather as generators. The distinction between these two categories of methods is that the former typically have the effect of changing the state of the "target object" (i.e., the object to which the method was applied), whereas the latter produce brand new objects without modifying the state of any already-existing object.

To illustrate, suppose that, in some client program, q and r are variables of type Polynomial representing the polynomials q and r, respectively. Then the call q.sum(r) returns a new instance of Polynomial that represents the polynomial (q+r) but has no effect upon the states of either q or r. (Had sum() been a mutator, you would have expected the state of q to have been changed to where it represented (q+r).)

You will further notice that the Polynomial class has no mutators. The instances of such a class are said to be immutable. You may not have realized it, but instances of the String class have this property, too.2

Representation

Choosing how to store the coefficients of a polynomial is a crucial step in developing the Polynomial class. The code that is provided to you includes a declaration of instance variable coeff[] (of type int[], i.e., array of int values) to serve this purpose.1. This is only a suggestion, however. Another reasonable approach would be for coeff to be of type ArrayList<Integer>. If you would prefer to take that approach, do so. The discussion that follows assumes that coeff[] is an array, but the ideas apply even if it were an ArrayList.

Take, for example, a Polynomial object that represents the polynomial

4 − 7x + x3 + 5x4

Then the value of its coeff[] instance variable would be (a reference to) the array

  0   1   2   3   4
+---+---+---+---+---+
| 4 | -7| 0 | 1 | 5 |
+---+---+---+---+---+ 

That is, for each i in the range 0..n, where n is the degree of the polynomial, coeff[i] holds the coefficient of xi


Suggestions for the Student

It is recommended that, in attempting to complete the source code of the Polynomial class, students tackle the tasks confronting them in something approximating this order:

  1. Complete the zero-argument constructor.
  2. Complete the valueAt() method.
  3. Improve the toString() method so that terms with zero coefficients are omitted (except in the case of the zero polynomial, which should translate to "0")
  4. Complete the sum() and difference() methods. For these, you should find the sumElementWise() and differenceElementWise() methods to be useful. Because these are static methods in the ArrayUtils class, you need to qualify them. For example, a call to the fomer would have the form

    ArrayUtils.sumElementWise(a,b)
    where a and b are arrays of type int[].
  5. Complete the product() method.
  6. Complete the rootOf() method.
  7. Improve the toString() method so that 1 coefficients are omitted and so that binary minus signs are used in place of unary minus signs. For example, rather than "2 + -4x + 1x^2 + -3x^3" being returned, it would be "2 - 4x + x^2 - 3x^3".

Testing

Given to you is a Java application, PolynomialTester, that you can use for running tests. Of course, depending upon which methods you've completed and which not, you may have to make modifications (e.g., commenting out certain code) in order to avoid exceptions from being thrown. Below is a sample user/program dialog.

Welcome to the Polynomial Tester Program!

1: Test Evaluate
2: Test Root Find
3: Test Arithmetic
4: Quit

Enter choice: 1
Enter the coefficients for polynomial p: -2 6 1

Polynomial p = -2 + 6x + x^2
Enter value at which to evaluate p (empty string to exit): 0.0
p(0.0) = -2.0

Polynomial p = -2 + 6x + x^2
Enter value at which to evaluate p (empty string to exit): 5.25
p(5.25) = 57.0625

Polynomial p = -2 + 6x + x^2
Enter value at which to evaluate p (empty string to exit): -7.5
p(-7.5) = 9.25

Polynomial p = -2 + 6x + x^2
Enter value at which to evaluate p (empty string to exit): 

1: Test Evaluate
2: Test Root Find
3: Test Arithmetic
4: Quit

Enter choice: 2
Enter the coefficients for polynomial p: -30 4 2

Polynomial p = -30 + 4x + 2x^2
Enter endpoints of interval in which to search for a root (empty string to exit): -10 0
Root found at z = -5.000004768; p(z) = 0.000076294

Polynomial p = -30 + 4x + 2x^2
Enter endpoints of interval in which to search for a root (empty string to exit): 0 8
Root found at z = 2.999996185; p(z) = -0.000061035

Polynomial p = -30 + 4x + 2x^2
Enter endpoints of interval in which to search for a root (empty string to exit): 5 10
java.lang.IllegalArgumentException: Values at endpoints have same sign!
	at Polynomial.rootOf(Polynomial.java:117)
	at PolynomialTester.testRootFind(PolynomialTester.java:139)
	at PolynomialTester.main(PolynomialTester.java:34)

Polynomial p = -30 + 4x + 2x^2
Enter endpoints of interval in which to search for a root (empty string to exit): 

1: Test Evaluate
2: Test Root Find
3: Test Arithmetic
4: Quit

Enter choice: 3
Enter the coefficients for polynomial p: 4 -8 3
p, of degree 2, is 4 - 8x + 3x^2

Enter the coefficients for polynomial q: -3 4 2 1
q, of degree 3, is -3 + 4x + 2x^2 + x^3

p+q is 1 - 4x + 5x^2 + x^3
p-q is 7 - 12x + x^2 - x^3
p*q is -12 + 40x - 33x^2 - 2x^4 + 3x^5


1: Test Evaluate
2: Test Root Find
3: Test Arithmetic
4: Quit

Enter choice: 4
Goodbye


Footnotes

[1] By convention, when we refer to a variable that is of an array type and we want to emphasize that fact, we include square brackets at the end of its name.

[2] Mutable strings are available by using the Java class StringBuilder.


Submitting Your Work

Use the CMPS 144 Student File Submission/Retrieval Utility to submit your Polynomial.java file into the prog2 folder.