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