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 }