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