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 }