001package hw3.test;
002
003import hw3.*;
004import org.junit.BeforeClass;
005import static org.junit.Assert.assertEquals;
006import static org.junit.Assert.assertFalse;
007import static org.junit.Assert.assertTrue;
008
009import org.junit.Before;
010import org.junit.Test;
011
012/**
013 * This class contains a set of test cases that can be used to test the
014 * implementation of the RatPoly class.
015 * <p>
016 */
017public final class RatPolyTest {
018  private final double JUNIT_DOUBLE_DELTA = 0.00001;
019
020  // get a RatNum for an integer
021  private static RatNum num(int i) {
022    return new RatNum(i);
023  }
024
025  // convenient way to make a RatPoly
026  private RatPoly poly(int coef, int expt) {
027    return new RatPoly(coef, expt);
028  }
029
030  // Convenient way to make a quadratic polynomial, arguments
031  // are just the coefficients, highest degree term to lowest
032  private RatPoly quadPoly(int x2, int x1, int x0) {
033    RatPoly ratPoly = new RatPoly(x2, 2);
034    return ratPoly.add(poly(x1, 1)).add(poly(x0, 0));
035  }
036
037  // convenience for valueOf
038  private RatPoly valueOf(String s) {
039    return RatPoly.valueOf(s);
040  }
041
042  // convenience for zero RatPoly
043  private RatPoly zero() {
044    return new RatPoly();
045  }
046
047  // only toString is tested here
048  private void eq(RatPoly p, String target) {
049    String t = p.toString();
050    assertEquals(target, t);
051  }
052
053  private void eq(RatPoly p, String target, String message) {
054    String t = p.toString();
055    assertEquals(message, target, t);
056  }
057
058  // parses s into p, and then checks that it is as anticipated
059  // forall i, valueOf(s).coeff(anticipDegree - i) = anticipCoeffForExpts(i)
060  // (anticipDegree - i) means that we expect coeffs to be expressed
061  // corresponding to decreasing expts
062  private void eqP(String s, int anticipDegree, RatNum[] anticipCoeffs) {
063    RatPoly p = valueOf(s);
064    assertEquals(anticipDegree, p.degree());
065    for (int i = 0; i <= anticipDegree; i++) {
066      assertTrue("wrong coeff; \n" + "anticipated: " + anticipCoeffs[i]
067          + "; received: " + p.getTerm(anticipDegree - i).getCoeff()
068          + "\n" + " received: " + p + " anticipated:" + s, p
069          .getTerm(anticipDegree - i).getCoeff().equals(
070              anticipCoeffs[i]));
071    }
072  }
073
074  // added convenience: express coeffs as ints
075  private void eqP(String s, int anticipDegree, int[] intCoeffs) {
076    RatNum[] coeffs = new RatNum[intCoeffs.length];
077    for (int i = 0; i < coeffs.length; i++) {
078      coeffs[i] = num(intCoeffs[i]);
079    }
080    eqP(s, anticipDegree, coeffs);
081  }
082
083  // make sure that unparsing a parsed string yields the string itself
084  private void assertToStringWorks(String s) {
085    assertEquals(s, valueOf(s).toString());
086  }
087
088  RatPoly poly1, neg_poly1, poly2, neg_poly2, poly3, neg_poly3;
089
090  //SetUp Method depends on RatPoly add and negate
091  //  Because all tests run this method before executing, ALL TESTS WILL FAIL
092  //  until .add and .negate do not throw exceptions. Also, any incorrectness
093  //  in .add and .negate may have unforseen consiquences elsewhere in the tests,
094  //  so it is a good idea to make sure these two methods are correct before
095  //  moving on to others.
096  //
097  //Tests that are intended to verify add or negate should not use variables
098  //declared in this setUp method
099  @Before
100  public void setUp(){
101    //poly1 = 1*x^1 + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5
102    poly1 = RatPoly.valueOf("1*x^1+2*x^2+3*x^3+4*x^4+5*x^5");
103
104    //neg_poly1 = -1*x^1 + -2*x^2 + -3*x^3 + -4*x^4 + -5*x^5
105    neg_poly1 = poly1.negate();
106
107    //poly2 = 6*x^2 + 7*x^3 + 8*x^4
108    poly2 = RatPoly.valueOf("6*x^2+7*x^3+8*x^4");
109
110    //neg_poly2 = -6*x^2 + -7*x^3 + -8*x^4
111    neg_poly2 = poly2.negate();
112
113    // poly3 = 9*x^3 + 10*x^4
114    poly3 = RatPoly.valueOf("9*x^3+10*x^4");
115
116    // neg_poly3 = -9*x^3 + -10*x^4
117    neg_poly3 = poly3.negate();
118  }
119
120  ///////////////////////////////////////////////////////////////////////////////////////
121  ////  Constructor
122  ///////////////////////////////////////////////////////////////////////////////////////   
123
124  @Test
125  public void testNoArgCtor() {
126    eq(new RatPoly(), "0");
127  }
128
129  @Test
130  public void testTwoArgCtorWithZeroExp() {
131    eq(poly(0, 0), "0");
132    eq(poly(0, 1), "0");
133    eq(poly(1, 0), "1");
134    eq(poly(-1, 0), "-1");
135  }
136
137  @Test
138  public void testTwoArgCtorWithOneExp() {
139    eq(poly(1, 1), "x");
140    eq(poly(-1, 1), "-x");
141  }
142
143  @Test
144  public void testTwoArgCtorWithLargeExp() {
145    eq(poly(1, 2), "x^2");
146    eq(poly(2, 2), "2*x^2");
147    eq(poly(2, 3), "2*x^3");
148    eq(poly(-2, 3), "-2*x^3"); 
149    eq(poly(-1, 3), "-x^3");
150  }
151
152  ///////////////////////////////////////////////////////////////////////////////////////
153  ////  isNaN Test
154  ///////////////////////////////////////////////////////////////////////////////////////     
155
156  @Test
157  public void testIsNaN() {
158    assertTrue(RatPoly.valueOf("NaN").isNaN());   
159  }
160
161  @Test
162  public void testIsNotNaN() {
163    assertFalse(RatPoly.valueOf("1").isNaN());
164    assertFalse(RatPoly.valueOf("1/2").isNaN());
165    assertFalse(RatPoly.valueOf("x+1").isNaN());
166    assertFalse(RatPoly.valueOf("x^2+x+1").isNaN());
167  }
168
169  @Test
170  public void testIsNaNEmptyPolynomial() {
171    RatPoly empty = new RatPoly();
172    assertTrue(empty.div(empty).isNaN());
173  }
174
175  ///////////////////////////////////////////////////////////////////////////////////////
176  ////  Value Of Test
177  ///////////////////////////////////////////////////////////////////////////////////////     
178
179  @Test
180  public void testValueOfSimple() {
181    eqP("0", 0, new int[] { 0 });
182    eqP("x", 1, new int[] { 1, 0 });
183    eqP("x^2", 2, new int[] { 1, 0, 0 });
184  }
185
186  @Test
187  public void testValueOfMultTerms() {
188    eqP("x^3+x^2", 3, new int[] { 1, 1, 0, 0 });
189    eqP("x^3-x^2", 3, new int[] { 1, -1, 0, 0 });
190    eqP("x^10+x^2", 10, new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 });
191  }
192
193  @Test
194  public void testValueOfLeadingNeg() {
195    eqP("-x^2", 2, new int[] { -1, 0, 0 });
196    eqP("-x^2+1", 2, new int[] { -1, 0, 1 });
197    eqP("-x^2+x", 2, new int[] { -1, 1, 0 });
198  }
199
200  @Test
201  public void testValueOfLeadingConstants() {
202    eqP("10*x", 1, new int[] { 10, 0 });
203    eqP("10*x^4+x^2", 4, new int[] { 10, 0, 1, 0, 0 });
204    eqP("10*x^4+100*x^2", 4, new int[] { 10, 0, 100, 0, 0 });
205    eqP("-10*x^4+100*x^2", 4, new int[] { -10, 0, 100, 0, 0 });
206  }
207
208  @Test
209  public void testValueOfRationalsSingleTerms() {
210    eqP("1/2", 0, new RatNum[] { num(1).div(num(2)) });
211    eqP("1/2*x", 1, new RatNum[] { num(1).div(num(2)), num(0) });
212    eqP("1/1000", 0, new RatNum[] { num(1).div(num(1000)) });
213    eqP("1/1000*x", 1, new RatNum[] { num(1).div(num(1000)), num(0) });
214  }
215
216  @Test
217  public void testValueOfRationalsMultipleTerms() {
218    eqP("x+1/3", 1, new RatNum[] { num(1), num(1).div(num(3)) });
219    eqP("1/2*x+1/3", 1, new RatNum[] { num(1).div(num(2)),
220        num(1).div(num(3)) });
221    eqP("1/2*x+3/2", 1, new RatNum[] { num(1).div(num(2)),
222        num(3).div(num(2)) });
223    eqP("1/2*x^3+3/2", 3, new RatNum[] { num(1).div(num(2)), num(0),
224        num(0), num(3).div(num(2)) });
225    eqP("1/2*x^3+3/2*x^2+1", 3, new RatNum[] { num(1).div(num(2)),
226        num(3).div(num(2)), num(0), num(1) });
227  }
228
229  @Test
230  public void testValueOfNaN() {
231    assertTrue(valueOf("NaN").isNaN());
232  }
233
234  ///////////////////////////////////////////////////////////////////////////////////////
235  ////  To String Test
236  ///////////////////////////////////////////////////////////////////////////////////////
237
238  @Test
239  public void testToStringSimple() {
240    assertToStringWorks("0");
241    assertToStringWorks("x");
242    assertToStringWorks("x^2");
243  }
244
245  @Test
246  public void testToStringMultTerms() {
247    assertToStringWorks("x^3+x^2");
248    assertToStringWorks("x^3-x^2");
249    assertToStringWorks("x^100+x^2");
250  }
251
252  @Test
253  public void testToStringLeadingNeg() {
254    assertToStringWorks("-x^2");
255    assertToStringWorks("-x^2+1");
256    assertToStringWorks("-x^2+x");
257  }
258
259  @Test
260  public void testToStringLeadingConstants() {
261    assertToStringWorks("10*x");
262    assertToStringWorks("10*x^100+x^2");
263    assertToStringWorks("10*x^100+100*x^2");
264    assertToStringWorks("-10*x^100+100*x^2");
265  }
266
267  @Test
268  public void testToStringRationalsSingleElems() {
269    assertToStringWorks("1/2");
270    assertToStringWorks("1/2*x");
271  }
272
273  @Test
274  public void testToStringRationalsMultiplElems() {
275    assertToStringWorks("x+1/3");
276    assertToStringWorks("1/2*x+1/3");
277    assertToStringWorks("1/2*x+3/2");
278    assertToStringWorks("1/2*x^10+3/2");
279    assertToStringWorks("1/2*x^10+3/2*x^2+1");
280  }
281
282  @Test
283  public void testToStringNaN() {
284    assertToStringWorks("NaN");
285  }
286
287  ///////////////////////////////////////////////////////////////////////////////////////
288  ////  Degree Test
289  ///////////////////////////////////////////////////////////////////////////////////////    
290
291  @Test // test degree is zero when it should be
292  public void testDegreeZero() {
293    assertEquals("x^0 degree 0", 0, poly(1, 0).degree());
294    assertEquals("0*x^100 degree 0", 0, poly(0, 100).degree());
295    assertEquals("0*x^0 degree 0", 0, poly(0, 0).degree());
296  }
297
298  @Test
299  public void testDegreeNonZero() {
300    assertEquals("x^1 degree 1", 1, poly(1, 1).degree());
301    assertEquals("x^100 degree 100", 100, poly(1, 100).degree());
302  }
303
304  @Test // test degree for multi termed polynomial
305  public void testDegreeNonZeroMultiTerm() {
306    assertEquals(poly1.toString() + " has Correct Degree", 5, poly1.degree());
307    assertEquals(poly2.toString() + " has Correct Degree", 4, poly2.degree());
308  }
309  
310  ///////////////////////////////////////////////////////////////////////////////////////
311  ////  Negate Tests
312  /////////////////////////////////////////////////////////////////////////////////////// 
313
314  @Test // test degree is zero when it should be
315  public void testNegateZero() {
316    assertEquals(RatPoly.ZERO, RatPoly.ZERO.negate());
317  }
318  
319  @Test // test degree is zero when it should be
320  public void testNegateNaN() {
321    assertEquals(RatPoly.NaN, RatPoly.NaN.negate());
322  }
323  
324  @Test // test degree is zero when it should be
325  public void testNegatePosToNeg() {
326    assertEquals(RatPoly.valueOf("-x-2*x^2-3*x^3-4*x^4-5*x^5"), poly1.negate());
327    assertEquals(RatPoly.valueOf("-6*x^2-7*x^3-8*x^4"), poly2.negate());
328    assertEquals(RatPoly.valueOf("-9*x^3-10*x^4"), poly3.negate());
329  }
330  
331  @Test // test degree is zero when it should be
332  public void testNegatNegToPos() {
333    assertEquals(poly1, RatPoly.valueOf("-x-2*x^2-3*x^3-4*x^4-5*x^5").negate());
334    assertEquals(poly2, RatPoly.valueOf("-6*x^2-7*x^3-8*x^4").negate());
335    assertEquals(poly3, RatPoly.valueOf("-9*x^3-10*x^4").negate());
336  }
337  
338  ///////////////////////////////////////////////////////////////////////////////////////
339  ////  Addition Test
340  ///////////////////////////////////////////////////////////////////////////////////////     
341  
342  @Test
343  public void testAddSingleTerm() {
344    eq(poly(1, 0).add(poly(1, 0)), "2");
345    eq(poly(1, 0).add(poly(5, 0)), "6");
346    eq(poly(1, 0).add(poly(-1, 0)), "0");
347    eq(poly(1, 1).add(poly(1, 1)), "2*x");
348    eq(poly(1, 2).add(poly(1, 2)), "2*x^2"); 
349  }
350
351  @Test
352  public void testAddMultipleTerm() {
353    RatPoly _XSqPlus2X = poly(1, 2).add(poly(1, 1)).add(poly(1, 1));
354    RatPoly _2XSqPlusX = poly(1, 2).add(poly(1, 2)).add(poly(1, 1));
355
356    eq(_XSqPlus2X, "x^2+2*x");
357    eq(_2XSqPlusX, "2*x^2+x");
358
359    eq(poly(1, 2).add(poly(1, 1)), "x^2+x");
360    eq(poly(1, 3).add(poly(1, 1)), "x^3+x");
361  }
362
363  // Note Polynomial is annotated as p
364  @Test // p1 + p2 = p3 , p1 != 0 && p2 != 0, p1.degree == p2.degree
365  public void testAddSameDegree(){
366    RatPoly temp = RatPoly.valueOf("3*x^1+4*x^2+5*x^3+6*x^4+7*x^5");
367    assertEquals(RatPoly.valueOf("4*x^1+6*x^2+8*x^3+10*x^4+12*x^5"), poly1.add(temp));
368
369    RatPoly temp2 = RatPoly.valueOf("-1*x^2-2*x^3-3*x^4");
370    assertEquals(RatPoly.valueOf("-7*x^2-9*x^3-11*x^4"), neg_poly2.add(temp2));
371  }
372
373  @Test // p1 + p2 = p3 , p1 != 0 && p2 != 0, p1.degree != p2.degree
374  public void testAddDifferentDegree(){
375    assertEquals(RatPoly.valueOf("1*x^1+8*x^2+10*x^3+12*x^4+5*x^5"), poly1.add(poly2));      
376    assertEquals(RatPoly.valueOf("-6*x^2-16*x^3-18*x^4"), neg_poly2.add(neg_poly3));
377  }
378
379  @Test // p + p = 2p
380  public void testAddWithItSelf() {
381    assertEquals(RatPoly.valueOf("2*x^1+4*x^2+6*x^3+8*x^4+10*x^5"), poly1.add(poly1));  
382    assertEquals(RatPoly.valueOf("-12*x^2-14*x^3-16*x^4"), neg_poly2.add(neg_poly2));
383  }
384
385  @Test // Addition Associativity (p1 + p2) + p3 = p1 + (p2 + p3)
386  public void testAddAssociativity() {
387    RatPoly operation1 = (poly1.add(poly2)).add(poly3);
388    RatPoly operation2 = (poly3.add(poly2)).add(poly1);
389    assertEquals(operation1, operation2);
390
391    operation1 = (poly1.add(neg_poly2)).add(neg_poly3);
392    operation2 = (neg_poly3.add(neg_poly2)).add(poly1);
393    assertEquals(operation1, operation2);
394  }
395
396  @Test // Addition Commutative Rule p1 + p2 = p2 + p1
397  public void testAddCommutativity() {
398    assertEquals(poly1.add(neg_poly2), neg_poly2.add(poly1));
399    assertEquals(neg_poly3.add(poly2), poly2.add(neg_poly3));
400  }
401
402  @Test // Zero Polynomial + Zero Polynomial == Zero Polynomial
403  public void testAddZeroToZero() {
404    assertEquals(RatPoly.ZERO, RatPoly.ZERO.add(RatPoly.ZERO));
405  }
406
407  @Test // Additive Identity p + Zero Polynomial == p && Zero Polynomial + p == p
408  public void testAddZeroToNonZero() {
409    assertEquals(poly1, RatPoly.ZERO.add(poly1));
410    assertEquals(poly1, poly1.add(RatPoly.ZERO));
411  }
412
413  @Test // Additive Inverse p + (-p) = 0
414  public void testAddInverse() {
415    assertEquals(RatPoly.ZERO, poly1.add(neg_poly1));
416    assertEquals(RatPoly.ZERO, poly2.add(neg_poly2));
417    assertEquals(RatPoly.ZERO, poly3.add(neg_poly3));
418  }
419
420  @Test // NaN + NaN == NaN
421  public void testAddNaNtoNaN() {
422    assertEquals(RatPoly.NaN, RatPoly.NaN.add(RatPoly.NaN));
423  }
424
425  @Test // t + NaN == NaN
426  public void testAddNaNtoNonNaN() {
427    assertEquals(RatPoly.NaN, RatPoly.NaN.add(poly1));
428    assertEquals(RatPoly.NaN, poly1.add(RatPoly.NaN));
429  }
430
431  ///////////////////////////////////////////////////////////////////////////////////////
432  ////  Subtraction Test
433  /////////////////////////////////////////////////////////////////////////////////////// 
434
435  //Also Tests Addition inverse property
436
437  @Test // p1 - p2 = p3 , p1 != 0 && p2 != 0, p1.degree == p2.degree
438  public void testSubtractSameDegree() {
439    RatPoly temp = RatPoly.valueOf("3*x^1+4*x^2+5*x^3+6*x^4+7*x^5");
440    assertEquals(RatPoly.valueOf("2*x^1+2*x^2+2*x^3+2*x^4+2*x^5"), temp.sub(poly1));
441
442    RatPoly temp2 = RatPoly.valueOf("-1*x^2-2*x^3-3*x^4");
443    assertEquals(RatPoly.valueOf("7*x^2+9*x^3+11*x^4"), poly2.sub(temp2));
444  }
445
446  @Test // p1 - p2 = p3 , p1 != 0 && p2 != 0, p1.degree != p2.degree
447  public void testSubtractDiffDegree() {
448    assertEquals(RatPoly.valueOf("1*x^1-4*x^2-4*x^3-4*x^4+5*x^5"), poly1.sub(poly2));
449    assertEquals(RatPoly.valueOf("-6*x^2-16*x^3-18*x^4"), neg_poly2.sub(poly3));
450  }
451
452  @Test // Zero Polynomial - Zero Polynomial == Zero Polynomial
453  public void testSubtractZeroFromZero() {
454    assertEquals(RatPoly.ZERO, RatPoly.ZERO.sub(RatPoly.ZERO));
455  }
456
457  //Following test method depends on correctness of negate
458  @Test // p - ZeroPolynomial == t && ZeroPolynomial - p == -p
459  public void testSubtractZeroAndNonZero() {
460    assertEquals(neg_poly1, RatPoly.ZERO.sub(poly1));
461    assertEquals(poly1, poly1.sub(RatPoly.ZERO));
462  }
463
464  @Test // NaN - NaN == NaN
465  public void testSubtractNaNtoNaN() {
466    assertEquals(RatPoly.NaN, RatPoly.NaN.sub(RatPoly.NaN));
467  }
468
469  @Test // p - NaN == NaN && NaN - p == NaN
470  public void testSubtractNaNtoNonNaN() {
471    assertEquals(RatPoly.NaN, RatPoly.NaN.sub(poly1));
472    assertEquals(RatPoly.NaN, poly1.sub(RatPoly.NaN));
473  }
474
475  ///////////////////////////////////////////////////////////////////////////////////////
476  ////  Remove zero when appropriate test
477  /////////////////////////////////////////////////////////////////////////////////////// 
478
479  @Test 
480  public void testZeroElim() {
481    // make sure zeros are removed from poly
482    eqP("1+0", 0, new int[] { 1 });
483    // test zero-elimination from intermediate result of sub
484    eq(quadPoly(1, 1, 1).sub(poly(1, 1)), "x^2+1");
485    // test internal cancellation of terms in mul.  (x+1)*(x-1)=x^2-1
486    eq(poly(1, 1).add(poly(1, 0)).mul(poly(1, 1).sub(poly(1, 0))), "x^2-1");
487  }
488
489  ///////////////////////////////////////////////////////////////////////////////////////
490  ////  Small Value Test
491  /////////////////////////////////////////////////////////////////////////////////////// 
492
493  @Test
494  public void testSmallCoeff() {
495    // try to flush out errors when small coefficients are in use.
496    eq(quadPoly(1, 1, 1).sub(poly(999, 1).div(poly(1000, 0))),
497        "x^2+1/1000*x+1");
498  }
499
500  ///////////////////////////////////////////////////////////////////////////////////////
501  ////  Multiplication Test
502  /////////////////////////////////////////////////////////////////////////////////////// 
503
504  @Test // p1 + p2 = p3 , p1 != 0 && p2 != 0, p1.degree == p2.degree
505  public void testMultiplicationSameDegree() {
506    eq(poly(0, 0).mul(poly(0, 0)), "0");
507    eq(poly(1, 0).mul(poly(1, 0)), "1");
508    eq(poly(1, 0).mul(poly(2, 0)), "2");
509    eq(poly(2, 0).mul(poly(2, 0)), "4");
510    RatPoly temp = RatPoly.valueOf("3*x^4+2");
511    assertEquals(RatPoly.valueOf("30*x^8+27*x^7+20*x^4+18*x^3"), temp.mul(poly3));
512  }
513
514  @Test // p1 + p2 = p3 , p1 != 0 && p2 != 0, p1.degree != p2.degree
515  public void testMultiplicationDiffDegree() {
516    RatPoly temp = RatPoly.valueOf("3*x^2");
517    assertEquals(RatPoly.valueOf("18*x^4+21*x^5+24*x^6"), temp.mul(poly2));
518    assertEquals(RatPoly.valueOf("27*x^5+30*x^6"), temp.mul(poly3));
519  }
520
521  @Test // Multiplication Associativity
522  public void testMultiplicationAssociativity() {
523    assertEquals(poly1.mul(poly2).mul(poly3), 
524        poly3.mul(poly2).mul(poly1));
525    assertEquals(poly1.mul(neg_poly2).mul(neg_poly3), 
526        neg_poly3.mul(neg_poly2).mul(poly1));
527  }
528
529  @Test // Multiplication Commutative
530  public void testMultiplicationCommutativity() {
531    assertEquals(poly1.mul(poly2), poly2.mul(poly1));
532    assertEquals(neg_poly3.mul(poly2), poly2.mul(neg_poly3));    
533  }
534
535  @Test // ZeroPolynomial * ZeroPolynomial == ZeroPolynomial
536  public void testMultiplicationZeroToZero() {
537    assertEquals(RatPoly.ZERO, RatPoly.ZERO.mul(RatPoly.ZERO));
538  }
539
540  @Test // p * ZeroPolynomial == ZeroPolynomial && ZeroPolynomial * p == ZeroPolynomial
541  public void testMultiplicationZeroToNonZero() {
542    assertEquals(RatPoly.ZERO, RatPoly.ZERO.mul(poly2));
543    assertEquals(RatPoly.ZERO, poly2.mul(RatPoly.ZERO));
544  }
545
546  @Test // NaN * NaN == NaN
547  public void testMultiplicationNaNtoNaN() {
548    assertEquals(RatPoly.NaN, RatPoly.NaN.mul(RatPoly.NaN));
549  }
550
551  @Test // p * NaN == NaN
552  public void testMultiplicationNaNtoNonNaN() {
553    assertEquals(RatPoly.NaN, RatPoly.NaN.mul(poly1));
554    assertEquals(RatPoly.NaN, poly1.mul(RatPoly.NaN));
555  }
556
557  @Test // p * 1 == p
558  public void testMultiplicationIdentity() {
559    assertEquals(poly2, poly2.mul(RatPoly.valueOf("1")));
560    assertEquals(neg_poly3, neg_poly3.mul(RatPoly.valueOf("1")));
561  }
562
563  @Test
564  public void testMulMultiplElem() {
565    eq(poly(1, 1).sub(poly(1, 0)).mul(poly(1, 1).add(poly(1, 0))), "x^2-1");
566  }
567
568    ///////////////////////////////////////////////////////////////////////////////////////
569    ////  Division Test
570    ///////////////////////////////////////////////////////////////////////////////////////     
571    
572  @Test
573  public void testDivEvaltoSingleCoeff() {
574    // 0/x = 0
575    eq(poly(0, 1).div(poly(1, 1)), "0");
576
577    // 2/1 = 2
578    eq(poly(2, 0).div(poly(1, 0)), "2");
579
580    // x/x = 1
581    eq(poly(1, 1).div(poly(1, 1)), "1");
582
583    // -x/x = -1
584    eq(poly(-1, 1).div(poly(1, 1)), "-1");
585
586    // x/-x = -1
587    eq(poly(1, 1).div(poly(-1, 1)), "-1");
588
589    // -x/-x = 1
590    eq(poly(-1, 1).div(poly(-1, 1)), "1");
591
592    // x^100/x^1000 = 0
593    eq(poly(1, 100).div(poly(1, 1000)), "0");
594  }
595
596  @Test
597  public void testDivtoSingleTerm() {
598
599    // 5x/5 = x
600    eq(poly(5, 1).div(poly(5, 0)), "x");
601
602    // -x^2/x = -x
603    eq(poly(-1, 2).div(poly(1, 1)), "-x");
604
605    // x^100/x = x^99
606    eq(poly(1, 100).div(poly(1, 1)), "x^99");
607
608    // x^99/x^98 = x
609    eq(poly(1, 99).div(poly(1, 98)), "x");
610
611    // x^10 / x = x^9 (r: 0)
612    eq(poly(1, 10).div(poly(1, 1)), "x^9");
613  }
614
615  @Test
616  public void testDivtoMultipleTerms() {
617    // x^10 / x^3+x^2 = x^7-x^6+x^5-x^4+x^3-x^2+x-1 (r: -x^2)
618    eq(poly(1, 10).div(poly(1, 3).add(poly(1, 2))),
619        "x^7-x^6+x^5-x^4+x^3-x^2+x-1");
620
621    // x^10 / x^3+x^2+x = x^7-x^6+x^4-x^3+x-1 (r: -x)
622    eq(poly(1, 10).div(poly(1, 3).add(poly(1, 2).add(poly(1, 1)))),
623        "x^7-x^6+x^4-x^3+x-1");
624
625    // 5x^2+5x/5 = x^2+x
626    eq(poly(5, 2).add(poly(5, 1)).div(poly(5, 0)), "x^2+x");
627
628    // x^10+x^5 / x = x^9+x^4 (r: 0)
629    eq(poly(1, 10).add(poly(1, 5)).div(poly(1, 1)), "x^9+x^4");
630
631    // x^10+x^5 / x^3 = x^7+x^2 (r: 0)
632    eq(poly(1, 10).add(poly(1, 5)).div(poly(1, 3)), "x^7+x^2");
633
634    // x^10+x^5 / x^3+x+3 = x^7-x^5-3*x^4+x^3+7*x^2+8*x-10
635    // (with remainder: 29*x^2+14*x-30)
636    eq(poly(1, 10).add(poly(1, 5)).div(
637        poly(1, 3).add(poly(1, 1)).add(poly(3, 0))),
638        "x^7-x^5-3*x^4+x^3+7*x^2+8*x-10");
639  }
640
641  @Test
642  public void testDivComplexI() {
643    // (x+1)*(x+1) = x^2+2*x+1
644    eq(poly(1, 2).add(poly(2, 1)).add(poly(1, 0)).div(
645        poly(1, 1).add(poly(1, 0))), "x+1");
646
647    // (x-1)*(x+1) = x^2-1
648    eq(poly(1, 2).add(poly(-1, 0)).div(poly(1, 1).add(poly(1, 0))), "x-1");
649  }
650
651  @Test
652  public void testDivComplexII() {
653    // x^8+2*x^6+8*x^5+2*x^4+17*x^3+11*x^2+8*x+3 =
654    // (x^3+2*x+1) * (x^5+7*x^2+2*x+3)
655    RatPoly large = poly(1, 8).add(poly(2, 6)).add(poly(8, 5)).add(
656        poly(2, 4)).add(poly(17, 3)).add(poly(11, 2)).add(poly(8, 1))
657        .add(poly(3, 0));
658
659    // x^3+2*x+1
660    RatPoly sub1 = poly(1, 3).add(poly(2, 1)).add(poly(1, 0));
661    // x^5+7*x^2+2*x+3
662    RatPoly sub2 = poly(1, 5).add(poly(7, 2)).add(poly(2, 1)).add(
663        poly(3, 0));
664
665    // just a last minute typo check...
666    eq(sub1.mul(sub2), large.toString());
667    eq(sub2.mul(sub1), large.toString());
668
669    eq(large.div(sub2), "x^3+2*x+1");
670    eq(large.div(sub1), "x^5+7*x^2+2*x+3");
671  }
672
673  @Test
674  public void testDivExamplesFromSpec() {
675    // seperated this test case out because it has a dependency on
676    // both "valueOf" and "div" functioning properly
677
678    // example 1 from spec
679    eq(valueOf("x^3-2*x+3").div(valueOf("3*x^2")), "1/3*x");
680    // example 2 from spec
681    eq(valueOf("x^2+2*x+15").div(valueOf("2*x^3")), "0");
682  }
683
684  @Test
685  public void testDivExampleFromPset() {
686    eq(valueOf("x^8+x^6+10*x^4+10*x^3+8*x^2+2*x+8").div(
687        valueOf("3*x^6+5*x^4+9*x^2+4*x+8")), "1/3*x^2-2/9");
688  }
689
690  @Test
691  public void testBigDiv() {
692    // don't "fix" the "infinite loop" in div by simply stopping after
693    // 50 terms!
694    eq(
695        valueOf("x^102").div(valueOf("x+1")),
696        "x^101-x^100+x^99-x^98+x^97-x^96+x^95-x^94+x^93-x^92+x^91-x^90+"
697            + "x^89-x^88+x^87-x^86+x^85-x^84+x^83-x^82+x^81-x^80+x^79-x^78+"
698            + "x^77-x^76+x^75-x^74+x^73-x^72+x^71-x^70+x^69-x^68+x^67-x^66+"
699            + "x^65-x^64+x^63-x^62+x^61-x^60+x^59-x^58+x^57-x^56+x^55-x^54+"
700            + "x^53-x^52+x^51-x^50+x^49-x^48+x^47-x^46+x^45-x^44+x^43-x^42+"
701            + "x^41-x^40+x^39-x^38+x^37-x^36+x^35-x^34+x^33-x^32+x^31-x^30+"
702            + "x^29-x^28+x^27-x^26+x^25-x^24+x^23-x^22+x^21-x^20+x^19-x^18+"
703            + "x^17-x^16+x^15-x^14+x^13-x^12+x^11-x^10+x^9-x^8+x^7-x^6+x^5-"
704            + "x^4+x^3-x^2+x-1");
705  }
706  
707  @Test // p / 0 = NaN
708  public void testDivByZero() {
709     assertEquals(RatPoly.NaN, poly2.div(RatPoly.ZERO));
710     assertEquals(RatPoly.NaN, neg_poly1.div(RatPoly.ZERO));
711     assertEquals(RatPoly.NaN, poly1.div(RatPoly.ZERO));
712  }
713    
714    @Test // Zero Polynomial / Zero Polynomial == NaN
715    public void testDivisionZeroFromZero() {
716      assertEquals(RatPoly.NaN, RatPoly.ZERO.div(RatPoly.ZERO));
717    }
718    
719    //Following test method depends on correctness of negate
720    @Test // p / Zero Polynomial == NaN && Zero Polynomial / p == 0
721    public void testDivisionZeroAndNonZero() {
722      assertEquals(RatPoly.ZERO, RatPoly.ZERO.div(poly1));
723    }
724    
725    @Test // NaN / NaN == NaN
726    public void testDivisionNaNtoNaN() {
727      assertEquals(RatPoly.NaN, RatPoly.NaN.div(RatPoly.NaN));
728    }
729    
730    @Test // p / NaN == NaN && NaN / p == NaN
731    public void testDivisionNaNtoNonNaN() {
732      assertEquals(RatPoly.NaN, RatPoly.NaN.div(poly1));
733        assertEquals(RatPoly.NaN, poly1.div(RatPoly.NaN));
734    }
735    
736    @Test // p / 1 == p
737    public void testDivisionByOne() {
738      assertEquals(poly2, poly2.div(RatPoly.valueOf("1")));
739    }
740    
741    ///////////////////////////////////////////////////////////////////////////////////////
742    ////  Immutable Test
743    ///////////////////////////////////////////////////////////////////////////////////////    
744    
745  @Test
746  public void testImmutabilityOfOperations() {
747    // not the most thorough test possible, but hopefully will
748    // catch the easy cases early on...
749    RatPoly one = poly(1, 0);
750    RatPoly two = poly(2, 0);
751    RatPoly empty = new RatPoly();
752
753    one.degree();
754    two.degree();
755    eq(one, "1", "Degree mutates receiver!");
756    eq(two, "2", "Degree mutates receiver!");
757
758    one.getTerm(0);
759    two.getTerm(0);
760    eq(one, "1", "Coeff mutates receiver!");
761    eq(two, "2", "Coeff mutates receiver!");
762
763    one.isNaN();
764    two.isNaN();
765    eq(one, "1", "isNaN mutates receiver!");
766    eq(two, "2", "isNaN mutates receiver!");
767
768    one.eval(0.0);
769    two.eval(0.0);
770    eq(one, "1", "eval mutates receiver!");
771    eq(two, "2", "eval mutates receiver!");
772
773    one.negate();
774    two.negate();
775    eq(one, "1", "Negate mutates receiver!");
776    eq(two, "2", "Negate mutates receiver!");
777
778    one.add(two);
779    eq(one, "1", "Add mutates receiver!");
780    eq(two, "2", "Add mutates argument!");
781
782    one.sub(two);
783    eq(one, "1", "Sub mutates receiver!");
784    eq(two, "2", "Sub mutates argument!");
785
786    one.mul(two);
787    eq(one, "1", "Mul mutates receiver!");
788    eq(two, "2", "Mul mutates argument!");
789
790    one.div(two);
791    eq(one, "1", "Div mutates receiver!");
792    eq(two, "2", "Div mutates argument!");
793
794    empty.div(new RatPoly());
795    assertFalse("Div Mutates reciever", empty.isNaN());
796  }
797
798    ///////////////////////////////////////////////////////////////////////////////////////
799    ////  Eval Test
800    /////////////////////////////////////////////////////////////////////////////////////// 
801  
802  @Test
803  public void testEvalZero() {
804    RatPoly zero = new RatPoly();
805    assertEquals(" 0 at 0 ", 0.0, zero.eval(0.0), JUNIT_DOUBLE_DELTA);
806    assertEquals(" 0 at 1 ", 0.0, zero.eval(1.0), JUNIT_DOUBLE_DELTA);
807    assertEquals(" 0 at 2 ", 0.0, zero.eval(2.0), JUNIT_DOUBLE_DELTA);
808  }
809
810  @Test
811  public void testEvalOne() {
812    RatPoly one = new RatPoly(1, 0);
813
814    assertEquals(" 1 at 0 ", 1.0, one.eval(0.0), JUNIT_DOUBLE_DELTA);
815    assertEquals(" 1 at 1 ", 1.0, one.eval(1.0), JUNIT_DOUBLE_DELTA);
816    assertEquals(" 1 at 1 ", 1.0, one.eval(2.0), JUNIT_DOUBLE_DELTA);
817  }
818
819  @Test
820  public void testEvalX() {
821    RatPoly _X = new RatPoly(1, 1);
822
823    assertEquals(" x at 0 ", 0.0, _X.eval(0.0), JUNIT_DOUBLE_DELTA);
824    assertEquals(" x at 1 ", 1.0, _X.eval(1.0), JUNIT_DOUBLE_DELTA);
825    assertEquals(" x at 2 ", 2.0, _X.eval(2.0), JUNIT_DOUBLE_DELTA);
826  }
827
828  @Test
829  public void testEval2X() {
830    RatPoly _2X = new RatPoly(2, 1);
831
832    assertEquals(" 2*x at 0 ", 0.0, _2X.eval(0.0), JUNIT_DOUBLE_DELTA);
833    assertEquals(" 2*x at 1 ", 2.0, _2X.eval(1.0), JUNIT_DOUBLE_DELTA);
834    assertEquals(" 2*x at 2 ", 4.0, _2X.eval(2.0), JUNIT_DOUBLE_DELTA);
835  }
836
837  @Test
838  public void testEvalXsq() {
839    RatPoly _XSq = new RatPoly(1, 2);
840    assertEquals(" x^2 at 0 ", 0.0, _XSq.eval(0.0), JUNIT_DOUBLE_DELTA);
841    assertEquals(" x^2 at 1 ", 1.0, _XSq.eval(1.0), JUNIT_DOUBLE_DELTA);
842    assertEquals(" x^2 at 2 ", 4.0, _XSq.eval(2.0), JUNIT_DOUBLE_DELTA);
843  }
844
845  @Test
846  public void testEvalXSq_minus_2X() {
847    RatPoly _2X = new RatPoly(2, 1);
848    RatPoly _XSq = new RatPoly(1, 2);
849    RatPoly _XSq_minus_2X = _XSq.sub(_2X);
850
851    assertEquals(" x^2-2*x at 0 ", 0.0, _XSq_minus_2X.eval(0.0), JUNIT_DOUBLE_DELTA);
852    assertEquals(" x^2-2*x at 1 ", -1.0, _XSq_minus_2X.eval(1.0), JUNIT_DOUBLE_DELTA);
853    assertEquals(" x^2-2*x at 2 ", 0.0, _XSq_minus_2X.eval(2.0), JUNIT_DOUBLE_DELTA);
854    assertEquals(" x^2-2*x at 3 ", 3.0, _XSq_minus_2X.eval(3.0), JUNIT_DOUBLE_DELTA);
855  }
856
857    ///////////////////////////////////////////////////////////////////////////////////////
858    ////  Get Term Test
859    ///////////////////////////////////////////////////////////////////////////////////////   
860  
861  @Test
862  public void testGetTerm() {
863    // getTerm already gets some grunt testing in eqP; checking an
864    // interesting
865    // input here...
866    RatPoly _XSqPlus2X = poly(1, 2).add(poly(1, 1)).add(poly(1, 1));
867    RatPoly _2XSqPlusX = poly(1, 2).add(poly(1, 2)).add(poly(1, 1));
868
869    assertEquals(RatTerm.ZERO, _XSqPlus2X.getTerm(-1));
870    assertEquals(RatTerm.ZERO, _XSqPlus2X.getTerm(-10));
871    assertEquals(RatTerm.ZERO, _2XSqPlusX.getTerm(-1));
872    assertEquals(RatTerm.ZERO, _2XSqPlusX.getTerm(-10));
873    assertEquals(RatTerm.ZERO, zero().getTerm(-10));
874    assertEquals(RatTerm.ZERO, zero().getTerm(-1));
875  }
876
877
878  private void assertIsNaNanswer(RatPoly nanAnswer) {
879    eq(nanAnswer, "NaN");
880  }
881
882    ///////////////////////////////////////////////////////////////////////////////////////
883    ////  Differentiate Test
884    /////////////////////////////////////////////////////////////////////////////////////// 
885  
886  // (NaN)' = NaN
887    @Test
888    public void testDifferentiateNaN(){
889      assertEquals(RatPoly.NaN, RatPoly.NaN.differentiate());
890    }
891    
892    // (RatPoly.ZERO)' = RatPoly.ZERO
893    @Test
894    public void testDifferentiateZero(){
895      assertEquals(RatPoly.ZERO, RatPoly.ZERO.differentiate());
896    }
897    
898    // constant a => (a)' = 0
899    @Test
900    public void testDifferentiateConstantNonZero(){
901      assertEquals(RatPoly.ZERO, RatPoly.valueOf("1").differentiate());
902      assertEquals(RatPoly.ZERO, RatPoly.valueOf("999").differentiate());
903    }
904    
905  @Test  //f(x) = x => f' = 1 
906  public void testDifferentiatetoOne() {
907    eq(RatPoly.valueOf("x").differentiate(), "1");
908  }
909    
910    // Constant Multiple Rule (af)' = af'
911    @Test
912    public void testDifferentiateMultiplicationRule(){
913      RatPoly a_constant = RatPoly.valueOf("2");
914      assertEquals(a_constant.mul(poly1.differentiate()), 
915          (a_constant.mul(poly1)).differentiate());
916      assertEquals(a_constant.mul(neg_poly2.differentiate()), 
917          (a_constant.mul(neg_poly2)).differentiate());
918    }
919    
920    // Polynomial Power Rule (ax^b) = (a*b)*x^(b-1) 
921    @Test
922    public void testDifferentiatePowerRule(){
923        assertEquals(RatPoly.valueOf("1+4*x+9*x^2+16*x^3+25*x^4"), poly1.differentiate());
924        assertEquals(RatPoly.valueOf("12*x+21*x^2+32*x^3"), poly2.differentiate());
925    }
926    
927    // Sum rule (f + g)' = f' + g'
928    @Test
929    public void testDifferentiateSumRule(){
930      assertEquals(((poly2).add(neg_poly3)).differentiate(), 
931          (poly2.differentiate()).add(neg_poly3.differentiate()));
932      assertEquals(((poly1).add(poly3)).differentiate(), 
933          (poly1.differentiate()).add(poly3.differentiate()));
934    }
935    
936    // Subtraction rule (f - g)' = f' - g'
937    @Test
938    public void testDifferentiateSubtractionRule(){
939      assertEquals(((poly2).sub(neg_poly3)).differentiate(), 
940          (poly2.differentiate()).sub(neg_poly3.differentiate()));
941      assertEquals(((poly1).sub(poly3)).differentiate(), 
942          (poly1.differentiate()).sub(poly3.differentiate()));
943    }
944    
945    // Product Rule h(x) = f(x)*g(x) => h'(x) = f'(x)g(x) + f(x)g'(x)
946    @Test
947    public void testDifferentiateProductRule(){
948      // Whole Number Coefficient
949      RatPoly init_product = poly1.mul(poly2);
950      RatPoly deriv_pt1 = (poly1.differentiate()).mul(poly2);
951      RatPoly deriv_pt2 = poly1.mul(poly2.differentiate());
952      
953      assertEquals(init_product.differentiate() , deriv_pt1.add(deriv_pt2));
954      
955      // Fractional Number Coefficient
956      init_product = neg_poly2.mul(poly3);
957      deriv_pt1 = (neg_poly2.differentiate()).mul(poly3);
958      deriv_pt2 = neg_poly2.mul(poly3.differentiate());
959      
960      assertEquals(init_product.differentiate() , deriv_pt1.add(deriv_pt2));
961    }
962
963  @Test
964  public void testDifferentiatetoMultipleTerms() {
965    eq(quadPoly(7, 5, 99).differentiate(), "14*x+5");
966    eq(quadPoly(3, 2, 1).differentiate(), "6*x+2");
967    eq(quadPoly(1, 0, 1).differentiate(), "2*x");
968  }
969
970  ///////////////////////////////////////////////////////////////////////////////////////
971  ////  Anti Differentiate Test
972  /////////////////////////////////////////////////////////////////////////////////////// 
973  //As stated in specification for any term b is assumed >= 0 and Integration Constant is Zero
974    //Note : AntiDerivative of f(x) = F(x) + c , f = F
975    //Note : c = Integration Constant
976    
977  @Test //AntiDifferentiate Basic functionality
978  public void testAntiDifferentiate() {
979    eq(poly(1, 0).antiDifferentiate(new RatNum(1)), "x+1");
980    eq(poly(2, 1).antiDifferentiate(new RatNum(1)), "x^2+1");      
981  }
982
983  @Test
984  public void testAntiDifferentiateWithQuadPoly() {
985    eq(quadPoly(0, 6, 2).antiDifferentiate(new RatNum(1)), "3*x^2+2*x+1");
986    eq(quadPoly(4, 6, 2).antiDifferentiate(new RatNum(0)),
987        "4/3*x^3+3*x^2+2*x");
988  }
989  
990  @Test // Constant Rule with zero f(x) = 0 => F = c
991    public void testAntiDifferentiateFromZero() {
992    // Zero
993      assertEquals(RatPoly.ZERO, RatPoly.ZERO.antiDifferentiate(RatNum.ZERO));
994      // Zero with integration constant 5
995      assertEquals(RatPoly.valueOf("5"), RatPoly.ZERO.antiDifferentiate(RatNum.valueOf("5")));
996  }
997  
998    // Constant Rule f(x) = c => F = c*x
999    @Test
1000    public void testAntiDifferentiateConstantRule() {
1001      // Zero Integration Constant
1002      assertEquals(RatPoly.valueOf("5*x"), RatPoly.valueOf("5").antiDifferentiate(RatNum.ZERO));
1003      
1004      // Non Zero Integration Constant
1005      assertEquals(RatPoly.valueOf("5*x+10"), RatPoly.valueOf("5").antiDifferentiate(RatNum.valueOf("10")));
1006    }
1007    
1008    // Constant Multiple Rule f(x) = c*g(x) => F = c*G(x)
1009    @Test
1010    public void testAntiDifferentiateConstantMultipleRule() {
1011      RatPoly a_constant = RatPoly.valueOf("7");
1012      RatPoly b_constant = RatPoly.valueOf("13");
1013      RatNum i_constant = RatNum.valueOf("11");
1014  
1015      assertEquals(((a_constant).mul(poly1)).antiDifferentiate(i_constant), 
1016           a_constant.mul(poly1.antiDifferentiate(RatNum.ZERO)).add(new RatPoly(new RatTerm(i_constant , 0))));
1017      
1018      assertEquals(((b_constant).mul(poly3)).antiDifferentiate(RatNum.ZERO), 
1019          b_constant.mul(poly3.antiDifferentiate(RatNum.ZERO)));
1020    }
1021    
1022    // Power Rule f(x) = x^a => F = (x^(a+1))/(a+1)
1023    @Test
1024    public void testAntiDifferentiatePowerRule() {
1025        assertEquals(RatPoly.valueOf("9/4*x^4+2*x^5"), poly3.antiDifferentiate(RatNum.ZERO));
1026        assertEquals(RatPoly.valueOf("2*x^3+7/4*x^4+8/5*x^5+1"), poly2.antiDifferentiate(RatNum.valueOf("1")));
1027    }
1028    
1029    // Sum Rule if h(x) = f(x) + g(x) => H(x) = F(x) + G(x)
1030    @Test
1031    public void testAntiDifferentiateSumRule() {
1032      assertEquals((poly1.add(poly2)).antiDifferentiate(RatNum.ZERO), 
1033          poly1.antiDifferentiate(RatNum.ZERO).add(poly2.antiDifferentiate(RatNum.ZERO)));
1034
1035      assertEquals((neg_poly3.add(neg_poly1)).antiDifferentiate(RatNum.valueOf("3")), 
1036          neg_poly3.antiDifferentiate(RatNum.ZERO).add(neg_poly1.antiDifferentiate(RatNum.ZERO))
1037          .add(new RatPoly(new RatTerm(RatNum.valueOf("3") , 0))));
1038    }
1039    
1040    // Difference Rule if h(x) = f(x) - g(x) => H(x) = F(x) - G(x)
1041    @Test
1042    public void testAntiDifferentiateDifferenceRule() {
1043      assertEquals((poly1.sub(poly2)).antiDifferentiate(RatNum.ZERO), 
1044          poly1.antiDifferentiate(RatNum.ZERO).sub(poly2.antiDifferentiate(RatNum.ZERO)));
1045
1046      assertEquals((neg_poly3.sub(neg_poly1)).antiDifferentiate(RatNum.valueOf("3")), 
1047          neg_poly3.antiDifferentiate(RatNum.ZERO).sub(neg_poly1.antiDifferentiate(RatNum.ZERO))
1048          .add(new RatPoly(new RatTerm(RatNum.valueOf("3") , 0))));
1049    }
1050    
1051    
1052
1053  @Test
1054  public void testAntiDifferentiateWithNaN() {
1055    assertIsNaNanswer(RatPoly.valueOf("NaN").antiDifferentiate(
1056        new RatNum(1)));
1057    assertIsNaNanswer(poly(1, 0).antiDifferentiate(new RatNum(1, 0)));
1058  }
1059
1060  ///////////////////////////////////////////////////////////////////////////////////////
1061  ////  Integrate Test
1062  /////////////////////////////////////////////////////////////////////////////////////// 
1063  
1064  @Test
1065  public void testIntegrateEqualBounds() {
1066    assertEquals( 0.0 , poly3.integrate(1, 1), JUNIT_DOUBLE_DELTA);
1067    assertEquals( 0.0 , poly1.integrate(0,0), JUNIT_DOUBLE_DELTA);
1068  }
1069  
1070  @Test
1071  public void testIntegrateBoundsDiffBy1() {
1072    assertEquals( 17.0 / 4.0 , poly3.integrate(0, 1), JUNIT_DOUBLE_DELTA);
1073    assertEquals( 71.0 / 20.0 , poly1.integrate(0,1), JUNIT_DOUBLE_DELTA);
1074  }
1075  
1076  @Test
1077  public void testIntegrateLowBoundGreaterThanHigh() {
1078    assertEquals( -19375.0 / 4.0 , poly3.integrate(0, -5), JUNIT_DOUBLE_DELTA);
1079    assertEquals( -5683.0 / 60.0 , poly1.integrate(2,1), JUNIT_DOUBLE_DELTA);
1080  }
1081  
1082  @Test
1083  public void testIntegrateLargeBoundDiff() {
1084    assertEquals( 20225000000.0, poly3.integrate(0, 100), JUNIT_DOUBLE_DELTA);
1085    assertEquals( 841409005000.0 , poly1.integrate(0,100), JUNIT_DOUBLE_DELTA);
1086  }
1087  
1088  @Test
1089  public void testIntegrateZero() {
1090    assertEquals("Integrate f(x) = 0 from 0 to 10", 0.0, RatPoly.ZERO.integrate(0, 10), JUNIT_DOUBLE_DELTA);
1091  }
1092  
1093  @Test
1094  public void testIntegrateOne() {
1095    assertEquals("Integrate f(x) = 1 from 0 to 10", 10.0, RatPoly.valueOf("1").integrate(0, 10), JUNIT_DOUBLE_DELTA);
1096  }
1097  
1098  @Test
1099  public void testIntegrateNaN() {
1100    assertEquals("NaN", RatPoly.valueOf("NaN").integrate(0, 1), Double.NaN, JUNIT_DOUBLE_DELTA);
1101  }
1102}