001    package ps1.test;
002    
003    import ps1.*;
004    
005    import org.junit.Test;
006    import org.junit.BeforeClass;
007    import static org.junit.Assert.*;
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    public final class RatPolyTest {
015        private final double JUNIT_DOUBLE_DELTA = 0.00001;
016    
017        // get a RatNum for an integer
018        private RatNum num(int i) {
019            return new RatNum(i);
020        }
021    
022        // convenient way to make a RatPoly
023        private RatPoly poly(int coef, int expt) {
024            return new RatPoly(coef, expt);
025        }
026    
027        // Convenient way to make a quadratic polynomial, arguments
028        // are just the coefficients, highest degree term to lowest
029        private RatPoly quadPoly(int x2, int x1, int x0) {
030            RatPoly ratPoly = new RatPoly(x2, 2);
031            return ratPoly.add(poly(x1, 1)).add(poly(x0, 0));
032        }
033    
034        // convenience for valueOf
035        private RatPoly valueOf(String s) {
036            return RatPoly.valueOf(s);
037        }
038    
039        // convenience for zero RatPoly
040        private RatPoly zero() {
041            return new RatPoly();
042        }
043    
044        // only toString is tested here
045        private void eq(RatPoly p, String target) {
046            String t = p.toString();
047            assertEquals(target, t);
048        }
049    
050        private void eq(RatPoly p, String target, String message) {
051            String t = p.toString();
052            assertEquals(message, target, t);
053        }
054    
055        // parses s into p, and then checks that it is as anticipated
056        // forall i, valueOf(s).coeff(anticipDegree - i) = anticipCoeffForExpts(i)
057        // (anticipDegree - i) means that we expect coeffs to be expressed
058        // corresponding to decreasing expts
059        private void eqP(String s, int anticipDegree, RatNum[] anticipCoeffs) {
060            RatPoly p = valueOf(s);
061            assertEquals(anticipDegree, p.degree());
062            for (int i = 0; i <= anticipDegree; i++) {
063                assertTrue("wrong coeff; \n" + "anticipated: " + anticipCoeffs[i]
064                        + "; received: " + p.getTerm(anticipDegree - i).getCoeff()
065                        + "\n" + " received: " + p + " anticipated:" + s, p
066                        .getTerm(anticipDegree - i).getCoeff().equals(
067                                anticipCoeffs[i]));
068            }
069        }
070    
071        // added convenience: express coeffs as ints
072        private void eqP(String s, int anticipDegree, int[] intCoeffs) {
073            RatNum[] coeffs = new RatNum[intCoeffs.length];
074            for (int i = 0; i < coeffs.length; i++) {
075                coeffs[i] = num(intCoeffs[i]);
076            }
077            eqP(s, anticipDegree, coeffs);
078        }
079    
080        // make sure that unparsing a parsed string yields the string itself
081        private void assertToStringWorks(String s) {
082            assertEquals(s, valueOf(s).toString());
083        }
084    
085        @Test
086        public void testNoArgCtor() {
087            eq(new RatPoly(), "0");
088        }
089    
090        @Test
091        public void testTwoArgCtor() {
092            eq(poly(0, 0), "0");
093            eq(poly(0, 1), "0");
094            eq(poly(1, 0), "1");
095            eq(poly(-1, 0), "-1");
096            eq(poly(1, 1), "x");
097            eq(poly(1, 2), "x^2");
098            eq(poly(2, 2), "2*x^2");
099            eq(poly(2, 3), "2*x^3");
100            eq(poly(-2, 3), "-2*x^3");
101            eq(poly(-1, 1), "-x");
102            eq(poly(-1, 3), "-x^3");
103        }
104    
105        @Test
106        public void testIsNaN() {
107            assertTrue(RatPoly.valueOf("NaN").isNaN());
108            assertFalse(RatPoly.valueOf("1").isNaN());
109            assertFalse(RatPoly.valueOf("1/2").isNaN());
110            assertFalse(RatPoly.valueOf("x+1").isNaN());
111            assertFalse(RatPoly.valueOf("x^2+x+1").isNaN());
112            RatPoly empty = new RatPoly();
113            assertTrue(empty.div(empty).isNaN());
114        }
115    
116        @Test
117        public void testValueOfSimple() {
118            eqP("0", 0, new int[] { 0 });
119            eqP("x", 1, new int[] { 1, 0 });
120            eqP("x^2", 2, new int[] { 1, 0, 0 });
121        }
122    
123        @Test
124        public void testValueOfMultTerms() {
125            eqP("x^3+x^2", 3, new int[] { 1, 1, 0, 0 });
126            eqP("x^3-x^2", 3, new int[] { 1, -1, 0, 0 });
127            eqP("x^10+x^2", 10, new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 });
128        }
129    
130        @Test
131        public void testValueOfLeadingNeg() {
132            eqP("-x^2", 2, new int[] { -1, 0, 0 });
133            eqP("-x^2+1", 2, new int[] { -1, 0, 1 });
134            eqP("-x^2+x", 2, new int[] { -1, 1, 0 });
135        }
136    
137        @Test
138        public void testValueOfLeadingConstants() {
139            eqP("10*x", 1, new int[] { 10, 0 });
140    
141            eqP("10*x^4+x^2", 4, new int[] { 10, 0, 1, 0, 0 });
142    
143            eqP("10*x^4+100*x^2", 4, new int[] { 10, 0, 100, 0, 0 });
144    
145            eqP("-10*x^4+100*x^2", 4, new int[] { -10, 0, 100, 0, 0 });
146        }
147    
148        @Test
149        public void testValueOfRationals() {
150            eqP("1/2", 0, new RatNum[] { num(1).div(num(2)) });
151            eqP("1/2*x", 1, new RatNum[] { num(1).div(num(2)), num(0) });
152            eqP("1/1000", 0, new RatNum[] { num(1).div(num(1000)) });
153            eqP("1/1000*x", 1, new RatNum[] { num(1).div(num(1000)), num(0) });
154            eqP("x+1/3", 1, new RatNum[] { num(1), num(1).div(num(3)) });
155            eqP("1/2*x+1/3", 1, new RatNum[] { num(1).div(num(2)),
156                    num(1).div(num(3)) });
157            eqP("1/2*x+3/2", 1, new RatNum[] { num(1).div(num(2)),
158                    num(3).div(num(2)) });
159            eqP("1/2*x^3+3/2", 3, new RatNum[] { num(1).div(num(2)), num(0),
160                    num(0), num(3).div(num(2)) });
161            eqP("1/2*x^3+3/2*x^2+1", 3, new RatNum[] { num(1).div(num(2)),
162                    num(3).div(num(2)), num(0), num(1) });
163        }
164    
165        @Test
166        public void testValueOfNaN() {
167            assertTrue(valueOf("NaN").isNaN());
168        }
169    
170        @Test
171        public void testToStringSimple() {
172            assertToStringWorks("0");
173            assertToStringWorks("x");
174            assertToStringWorks("x^2");
175        }
176    
177        @Test
178        public void testToStringMultTerms() {
179            assertToStringWorks("x^3+x^2");
180            assertToStringWorks("x^3-x^2");
181            assertToStringWorks("x^100+x^2");
182        }
183    
184        @Test
185        public void testToStringLeadingNeg() {
186            assertToStringWorks("-x^2");
187            assertToStringWorks("-x^2+1");
188            assertToStringWorks("-x^2+x");
189        }
190    
191        @Test
192        public void testToStringLeadingConstants() {
193            assertToStringWorks("10*x");
194            assertToStringWorks("10*x^100+x^2");
195            assertToStringWorks("10*x^100+100*x^2");
196            assertToStringWorks("-10*x^100+100*x^2");
197        }
198    
199        @Test
200        public void testToStringRationals() {
201            assertToStringWorks("1/2");
202            assertToStringWorks("1/2*x");
203            assertToStringWorks("x+1/3");
204            assertToStringWorks("1/2*x+1/3");
205            assertToStringWorks("1/2*x+3/2");
206            assertToStringWorks("1/2*x^10+3/2");
207            assertToStringWorks("1/2*x^10+3/2*x^2+1");
208        }
209    
210        @Test
211        public void testToStringNaN() {
212            assertToStringWorks("NaN");
213        }
214    
215        @Test
216        public void testDegree() {
217            assertEquals("x^0 degree 0", 0, poly(1, 0).degree());
218            assertEquals("x^1 degree 1", 1, poly(1, 1).degree());
219            assertEquals("x^100 degree 100", 100, poly(1, 100).degree());
220            assertEquals("0*x^100 degree 0", 0, poly(0, 100).degree());
221            assertEquals("0*x^0 degree 0", 0, poly(0, 0).degree());
222        }
223    
224        @Test
225        public void testAdd() {
226            RatPoly _XSqPlus2X = poly(1, 2).add(poly(1, 1)).add(poly(1, 1));
227            RatPoly _2XSqPlusX = poly(1, 2).add(poly(1, 2)).add(poly(1, 1));
228    
229            eq(poly(1, 0).add(poly(1, 0)), "2");
230            eq(poly(1, 0).add(poly(5, 0)), "6");
231            eq(poly(1, 0).add(poly(-1, 0)), "0");
232            eq(poly(1, 1).add(poly(1, 1)), "2*x");
233            eq(poly(1, 2).add(poly(1, 2)), "2*x^2");
234            eq(poly(1, 2).add(poly(1, 1)), "x^2+x");
235            eq(_XSqPlus2X, "x^2+2*x");
236            eq(_2XSqPlusX, "2*x^2+x");
237            eq(poly(1, 3).add(poly(1, 1)), "x^3+x");
238        }
239    
240        @Test
241        public void testSub() {
242            eq(poly(1, 1).sub(poly(1, 0)), "x-1");
243            eq(poly(1, 1).add(poly(1, 0)), "x+1");
244            eq(poly(1, 0).sub(poly(1, 0)), "0");
245        }
246    
247        @Test
248        public void testZeroElim() {
249            // make sure zeros are removed from poly
250            eqP("1+0", 0, new int[] { 1 });
251            // test zero-elimination from intermediate result of sub
252            eq(quadPoly(1, 1, 1).sub(poly(1, 1)), "x^2+1");
253            // test internal cancellation of terms in mul.  (x+1)*(x-1)=x^2-1
254            eq(poly(1, 1).add(poly(1, 0)).mul(poly(1, 1).sub(poly(1, 0))), "x^2-1");
255        }
256    
257        @Test
258        public void testSmallCoeff() {
259            // try to flush out errors when small coefficients are in use.
260            eq(quadPoly(1, 1, 1).sub(poly(999, 1).div(poly(1000, 0))),
261                    "x^2+1/1000*x+1");
262        }
263    
264        @Test
265        public void testMul() {
266            eq(poly(0, 0).mul(poly(0, 0)), "0");
267            eq(poly(1, 0).mul(poly(1, 0)), "1");
268            eq(poly(1, 0).mul(poly(2, 0)), "2");
269            eq(poly(2, 0).mul(poly(2, 0)), "4");
270            eq(poly(1, 0).mul(poly(1, 1)), "x");
271            eq(poly(1, 1).mul(poly(1, 1)), "x^2");
272            eq(poly(1, 1).sub(poly(1, 0)).mul(poly(1, 1).add(poly(1, 0))), "x^2-1");
273        }
274    
275        private void testOpsWithNaN(RatPoly p) {
276            RatPoly nan = RatPoly.valueOf("NaN");
277            eq(p.add(nan), "NaN");
278            eq(nan.add(p), "NaN");
279            eq(p.sub(nan), "NaN");
280            eq(nan.sub(p), "NaN");
281            eq(p.mul(nan), "NaN");
282            eq(nan.mul(p), "NaN");
283            eq(p.div(nan), "NaN");
284            eq(nan.div(p), "NaN");
285        }
286    
287        @Test
288        public void testOpsWithNaN() {
289            testOpsWithNaN(poly(0, 0));
290            testOpsWithNaN(poly(0, 1));
291            testOpsWithNaN(poly(1, 0));
292            testOpsWithNaN(poly(1, 1));
293            testOpsWithNaN(poly(2, 0));
294            testOpsWithNaN(poly(2, 1));
295            testOpsWithNaN(poly(0, 2));
296            testOpsWithNaN(poly(1, 2));
297        }
298    
299        @Test
300        public void testImmutabilityOfOperations() {
301            // not the most thorough test possible, but hopefully will
302            // catch the easy cases early on...
303            RatPoly one = poly(1, 0);
304            RatPoly two = poly(2, 0);
305            RatPoly empty = new RatPoly();
306    
307            one.degree();
308            two.degree();
309            eq(one, "1", "Degree mutates receiver!");
310            eq(two, "2", "Degree mutates receiver!");
311    
312            one.getTerm(0);
313            two.getTerm(0);
314            eq(one, "1", "Coeff mutates receiver!");
315            eq(two, "2", "Coeff mutates receiver!");
316    
317            one.isNaN();
318            two.isNaN();
319            eq(one, "1", "isNaN mutates receiver!");
320            eq(two, "2", "isNaN mutates receiver!");
321    
322            one.eval(0.0);
323            two.eval(0.0);
324            eq(one, "1", "eval mutates receiver!");
325            eq(two, "2", "eval mutates receiver!");
326    
327            one.negate();
328            two.negate();
329            eq(one, "1", "Negate mutates receiver!");
330            eq(two, "2", "Negate mutates receiver!");
331    
332            one.add(two);
333            eq(one, "1", "Add mutates receiver!");
334            eq(two, "2", "Add mutates argument!");
335    
336            one.sub(two);
337            eq(one, "1", "Sub mutates receiver!");
338            eq(two, "2", "Sub mutates argument!");
339    
340            one.mul(two);
341            eq(one, "1", "Mul mutates receiver!");
342            eq(two, "2", "Mul mutates argument!");
343    
344            one.div(two);
345            eq(one, "1", "Div mutates receiver!");
346            eq(two, "2", "Div mutates argument!");
347    
348            empty.div(new RatPoly());
349            assertFalse("Div Mutates reciever", empty.isNaN());
350        }
351    
352        @Test
353        public void testEval() {
354            RatPoly zero = new RatPoly();
355            RatPoly one = new RatPoly(1, 0);
356            RatPoly _X = new RatPoly(1, 1);
357            RatPoly _2X = new RatPoly(2, 1);
358            RatPoly _XSq = new RatPoly(1, 2);
359    
360            assertEquals(" 0 at 0 ", 0.0, zero.eval(0.0), JUNIT_DOUBLE_DELTA);
361            assertEquals(" 0 at 1 ", 0.0, zero.eval(1.0), JUNIT_DOUBLE_DELTA);
362            assertEquals(" 0 at 2 ", 0.0, zero.eval(2.0), JUNIT_DOUBLE_DELTA);
363            assertEquals(" 1 at 0 ", 1.0, one.eval(0.0), JUNIT_DOUBLE_DELTA);
364            assertEquals(" 1 at 1 ", 1.0, one.eval(1.0), JUNIT_DOUBLE_DELTA);
365            assertEquals(" 1 at 1 ", 1.0, one.eval(2.0), JUNIT_DOUBLE_DELTA);
366    
367            assertEquals(" x at 0 ", 0.0, _X.eval(0.0), JUNIT_DOUBLE_DELTA);
368            assertEquals(" x at 1 ", 1.0, _X.eval(1.0), JUNIT_DOUBLE_DELTA);
369            assertEquals(" x at 2 ", 2.0, _X.eval(2.0), JUNIT_DOUBLE_DELTA);
370    
371            assertEquals(" 2*x at 0 ", 0.0, _2X.eval(0.0), JUNIT_DOUBLE_DELTA);
372            assertEquals(" 2*x at 1 ", 2.0, _2X.eval(1.0), JUNIT_DOUBLE_DELTA);
373            assertEquals(" 2*x at 2 ", 4.0, _2X.eval(2.0), JUNIT_DOUBLE_DELTA);
374    
375            assertEquals(" x^2 at 0 ", 0.0, _XSq.eval(0.0), JUNIT_DOUBLE_DELTA);
376            assertEquals(" x^2 at 1 ", 1.0, _XSq.eval(1.0), JUNIT_DOUBLE_DELTA);
377            assertEquals(" x^2 at 2 ", 4.0, _XSq.eval(2.0), JUNIT_DOUBLE_DELTA);
378    
379            RatPoly _XSq_minus_2X = _XSq.sub(_2X);
380    
381            assertEquals(" x^2-2*x at 0 ", 0.0, _XSq_minus_2X.eval(0.0), JUNIT_DOUBLE_DELTA);
382            assertEquals(" x^2-2*x at 1 ", -1.0, _XSq_minus_2X.eval(1.0), JUNIT_DOUBLE_DELTA);
383            assertEquals(" x^2-2*x at 2 ", 0.0, _XSq_minus_2X.eval(2.0), JUNIT_DOUBLE_DELTA);
384            assertEquals(" x^2-2*x at 3 ", 3.0, _XSq_minus_2X.eval(3.0), JUNIT_DOUBLE_DELTA);
385        }
386    
387        @Test
388        public void testGetTerm() {
389            // getTerm already gets some grunt testing in eqP; checking an
390            // interesting
391            // input here...
392            RatPoly _XSqPlus2X = poly(1, 2).add(poly(1, 1)).add(poly(1, 1));
393            RatPoly _2XSqPlusX = poly(1, 2).add(poly(1, 2)).add(poly(1, 1));
394    
395            assertEquals(RatTerm.ZERO, _XSqPlus2X.getTerm(-1));
396            assertEquals(RatTerm.ZERO, _XSqPlus2X.getTerm(-10));
397            assertEquals(RatTerm.ZERO, _2XSqPlusX.getTerm(-1));
398            assertEquals(RatTerm.ZERO, _2XSqPlusX.getTerm(-10));
399            assertEquals(RatTerm.ZERO, zero().getTerm(-10));
400            assertEquals(RatTerm.ZERO, zero().getTerm(-1));
401        }
402    
403        @Test
404        public void testDiv() {
405            // 0/x = 0
406            eq(poly(0, 1).div(poly(1, 1)), "0");
407    
408            // 2/1 = 2
409            eq(poly(2, 0).div(poly(1, 0)), "2");
410    
411            // x/x = 1
412            eq(poly(1, 1).div(poly(1, 1)), "1");
413    
414            // 5x/5 = x
415            eq(poly(5, 1).div(poly(5, 0)), "x");
416    
417            // -x/x = -1
418            eq(poly(-1, 1).div(poly(1, 1)), "-1");
419    
420            // x/-x = -1
421            eq(poly(1, 1).div(poly(-1, 1)), "-1");
422    
423            // -x/-x = 1
424            eq(poly(-1, 1).div(poly(-1, 1)), "1");
425    
426            // -x^2/x = -x
427            eq(poly(-1, 2).div(poly(1, 1)), "-x");
428    
429            // x^100/x^1000 = 0
430            eq(poly(1, 100).div(poly(1, 1000)), "0");
431    
432            // x^100/x = x^99
433            eq(poly(1, 100).div(poly(1, 1)), "x^99");
434    
435            // x^99/x^98 = x
436            eq(poly(1, 99).div(poly(1, 98)), "x");
437    
438            // x^10 / x = x^9 (r: 0)
439            eq(poly(1, 10).div(poly(1, 1)), "x^9");
440    
441            // x^10 / x^3+x^2 = x^7-x^6+x^5-x^4+x^3-x^2+x-1 (r: -x^2)
442            eq(poly(1, 10).div(poly(1, 3).add(poly(1, 2))),
443                    "x^7-x^6+x^5-x^4+x^3-x^2+x-1");
444    
445            // x^10 / x^3+x^2+x = x^7-x^6+x^4-x^3+x-1 (r: -x)
446            eq(poly(1, 10).div(poly(1, 3).add(poly(1, 2).add(poly(1, 1)))),
447                    "x^7-x^6+x^4-x^3+x-1");
448    
449            // 5x^2+5x/5 = x^2+x
450            eq(poly(5, 2).add(poly(5, 1)).div(poly(5, 0)), "x^2+x");
451    
452            // x^10+x^5 / x = x^9+x^4 (r: 0)
453            eq(poly(1, 10).add(poly(1, 5)).div(poly(1, 1)), "x^9+x^4");
454    
455            // x^10+x^5 / x^3 = x^7+x^2 (r: 0)
456            eq(poly(1, 10).add(poly(1, 5)).div(poly(1, 3)), "x^7+x^2");
457    
458            // x^10+x^5 / x^3+x+3 = x^7-x^5-3*x^4+x^3+7*x^2+8*x-10
459            // (with remainder: 29*x^2+14*x-30)
460            eq(poly(1, 10).add(poly(1, 5)).div(
461                    poly(1, 3).add(poly(1, 1)).add(poly(3, 0))),
462                    "x^7-x^5-3*x^4+x^3+7*x^2+8*x-10");
463        }
464    
465        @Test
466        public void testDivComplexI() {
467            // (x+1)*(x+1) = x^2+2*x+1
468            eq(poly(1, 2).add(poly(2, 1)).add(poly(1, 0)).div(
469                    poly(1, 1).add(poly(1, 0))), "x+1");
470    
471            // (x-1)*(x+1) = x^2-1
472            eq(poly(1, 2).add(poly(-1, 0)).div(poly(1, 1).add(poly(1, 0))), "x-1");
473        }
474    
475        @Test
476        public void testDivComplexII() {
477            // x^8+2*x^6+8*x^5+2*x^4+17*x^3+11*x^2+8*x+3 =
478            // (x^3+2*x+1) * (x^5+7*x^2+2*x+3)
479            RatPoly large = poly(1, 8).add(poly(2, 6)).add(poly(8, 5)).add(
480                    poly(2, 4)).add(poly(17, 3)).add(poly(11, 2)).add(poly(8, 1))
481                    .add(poly(3, 0));
482    
483            // x^3+2*x+1
484            RatPoly sub1 = poly(1, 3).add(poly(2, 1)).add(poly(1, 0));
485            // x^5+7*x^2+2*x+3
486            RatPoly sub2 = poly(1, 5).add(poly(7, 2)).add(poly(2, 1)).add(
487                    poly(3, 0));
488    
489            // just a last minute typo check...
490            eq(sub1.mul(sub2), large.toString());
491            eq(sub2.mul(sub1), large.toString());
492    
493            eq(large.div(sub2), "x^3+2*x+1");
494            eq(large.div(sub1), "x^5+7*x^2+2*x+3");
495        }
496    
497        @Test
498        public void testDivExamplesFromSpec() {
499            // seperated this test case out because it has a dependency on
500            // both "valueOf" and "div" functioning properly
501    
502            // example 1 from spec
503            eq(valueOf("x^3-2*x+3").div(valueOf("3*x^2")), "1/3*x");
504            // example 2 from spec
505            eq(valueOf("x^2+2*x+15").div(valueOf("2*x^3")), "0");
506        }
507    
508        @Test
509        public void testDivExampleFromPset() {
510            eq(valueOf("x^8+x^6+10*x^4+10*x^3+8*x^2+2*x+8").div(
511                    valueOf("3*x^6+5*x^4+9*x^2+4*x+8")), "1/3*x^2-2/9");
512        }
513    
514        @Test
515        public void testBigDiv() {
516            // don't "fix" the "infinite loop" in div by simply stopping after
517            // 50 terms!
518            eq(
519                    valueOf("x^102").div(valueOf("x+1")),
520                    "x^101-x^100+x^99-x^98+x^97-x^96+x^95-x^94+x^93-x^92+x^91-x^90+"
521                            + "x^89-x^88+x^87-x^86+x^85-x^84+x^83-x^82+x^81-x^80+x^79-x^78+"
522                            + "x^77-x^76+x^75-x^74+x^73-x^72+x^71-x^70+x^69-x^68+x^67-x^66+"
523                            + "x^65-x^64+x^63-x^62+x^61-x^60+x^59-x^58+x^57-x^56+x^55-x^54+"
524                            + "x^53-x^52+x^51-x^50+x^49-x^48+x^47-x^46+x^45-x^44+x^43-x^42+"
525                            + "x^41-x^40+x^39-x^38+x^37-x^36+x^35-x^34+x^33-x^32+x^31-x^30+"
526                            + "x^29-x^28+x^27-x^26+x^25-x^24+x^23-x^22+x^21-x^20+x^19-x^18+"
527                            + "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-"
528                            + "x^4+x^3-x^2+x-1");
529        }
530    
531        private void assertIsNaNanswer(RatPoly nanAnswer) {
532            eq(nanAnswer, "NaN");
533        }
534    
535        @Test
536        public void testDivByZero() {
537            RatPoly nanAnswer;
538            nanAnswer = poly(1, 0).div(zero());
539            assertIsNaNanswer(nanAnswer);
540    
541            nanAnswer = poly(1, 1).div(zero());
542            assertIsNaNanswer(nanAnswer);
543        }
544    
545        @Test
546        public void testDivByPolyWithNaN() {
547            RatPoly nan_x2 = poly(1, 2).mul(poly(1, 1).div(zero()));
548            RatPoly one_x1 = new RatPoly(1, 1);
549    
550            assertIsNaNanswer(nan_x2.div(one_x1));
551            assertIsNaNanswer(one_x1.div(nan_x2));
552            assertIsNaNanswer(nan_x2.div(zero()));
553            assertIsNaNanswer(zero().div(nan_x2));
554            assertIsNaNanswer(nan_x2.div(nan_x2));
555        }
556    
557        @Test
558        public void testDifferentiate() {
559            eq(poly(1, 1).differentiate(), "1");
560            eq(quadPoly(7, 5, 99).differentiate(), "14*x+5");
561            eq(quadPoly(3, 2, 1).differentiate(), "6*x+2");
562            eq(quadPoly(1, 0, 1).differentiate(), "2*x");
563            assertIsNaNanswer(RatPoly.valueOf("NaN").differentiate());
564        }
565    
566        @Test
567        public void testAntiDifferentiate() {
568            eq(poly(1, 0).antiDifferentiate(new RatNum(1)), "x+1");
569            eq(poly(2, 1).antiDifferentiate(new RatNum(1)), "x^2+1");
570            eq(quadPoly(0, 6, 2).antiDifferentiate(new RatNum(1)), "3*x^2+2*x+1");
571            eq(quadPoly(4, 6, 2).antiDifferentiate(new RatNum(0)),
572                    "4/3*x^3+3*x^2+2*x");
573    
574            assertIsNaNanswer(RatPoly.valueOf("NaN").antiDifferentiate(
575                    new RatNum(1)));
576            assertIsNaNanswer(poly(1, 0).antiDifferentiate(new RatNum(1, 0)));
577        }
578    
579        @Test
580        public void testIntegrate() {
581            assertEquals("one from 0 to 1", 1.0, poly(1, 0).integrate(0, 1), JUNIT_DOUBLE_DELTA);
582            assertEquals("2x from 1 to -2", 3.0, poly(2, 1).integrate(1, -2), JUNIT_DOUBLE_DELTA);
583            assertEquals("7*x^2+6*x+2 from 1 to 5", 369.33333333, quadPoly(7, 6, 2).integrate(1, 5), JUNIT_DOUBLE_DELTA);
584            assertEquals("NaN", RatPoly.valueOf("NaN").integrate(0, 1), Double.NaN, JUNIT_DOUBLE_DELTA);
585        }
586    
587    }