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 import static org.hamcrest.CoreMatchers.*;
009
010 /**
011 * This class contains a set of test cases that can be used to test the
012 * implementation of the RatPoly class.
013 */
014 public final class RatTermTest {
015
016 // Get a RatNum for in an integer
017 private static RatNum num(int i) {
018 return new RatNum(i);
019 }
020
021 private static RatNum num(int i, int j) {
022 return new RatNum(i, j);
023 }
024
025 private static final RatNum nanNum = (num(1)).div(num(0));
026
027 private static final RatTerm nanTerm = new RatTerm(nanNum, 3);
028
029 // Convenient way to make a RatTerm equals to coeff*x^expt.
030 private static RatTerm term(int coeff, int expt) {
031 return new RatTerm(num(coeff), expt);
032 }
033
034 // Convenient way to make a RatTerm equals to num/denom*x^expt.
035 private static RatTerm term(int numer, int denom, int expt) {
036 return new RatTerm(num(numer, denom), expt);
037 }
038
039 @Test
040 public void testCtor() {
041 term(1, 0);
042 term(2, 3);
043 term(4, 3, 6);
044 term(-2, 7, 3);
045 }
046
047 @Test
048 public void testCtorZeroCoeff() {
049 term(0, 0);
050 term(0, 1);
051 }
052
053 @Test
054 public void testCtorNaN() {
055 term(3, 0, 0);
056 }
057
058 @Test
059 public void testGetCoeff() {
060 // Simple cases
061 assertEquals(num(3), term(3, 1).getCoeff());
062 assertEquals(num(2, 5), term(2, 5, 2).getCoeff());
063
064 // Check zero
065 assertEquals(num(0), term(0, 0).getCoeff());
066
067 // Check negative coeff
068 assertEquals(num(-2, 3), term(-2, 3, 2).getCoeff());
069
070 // Check NaN
071 assertEquals(nanNum, term(3, 0, 4).getCoeff());
072 }
073
074 @Test
075 public void testGetExpt() {
076 // Simple
077 assertEquals(4, term(2, 4).getExpt());
078
079 // Zero always have zero expt
080 assertEquals(0, term(0, 0).getExpt());
081 assertEquals(0, term(0, 1).getExpt());
082
083 }
084
085 @Test
086 public void testIsNaN() {
087 assertTrue(term(5, 0, 0).isNaN());
088
089 // Check that 0/0*x^4 isNaN instead of zero
090 assertTrue(term(0, 0, 4).isNaN());
091
092 // Check for false positives
093 assertFalse(term(2, 3, 2).isNaN());
094 }
095
096 @Test
097 public void testIsZero() {
098 assertTrue(term(0, 0).isZero());
099 assertTrue(term(0, 1).isZero());
100 assertTrue(term(0, 4, 3).isZero());
101 assertTrue(term(0, -2, 2).isZero());
102
103 // Check for false positives
104 assertFalse(term(1, 3, 0).isZero());
105
106 // Check that 0/0*x^4 is not zero
107 assertFalse(term(0, 0, 4).isZero());
108 }
109
110 @Test
111 public void testEval() {
112 assertEquals(0.0, term(0, 0).eval(5.0), 0.0000001);
113 assertEquals(0.0, term(0, 5).eval(1.2), 0.0000001);
114 assertEquals(2.0, term(2, 0).eval(3.1), 0.0000001);
115 assertEquals(1.0, term(1, 0).eval(100.0), 0.0000001);
116 assertEquals(35.0, term(5, 1).eval(7.0), 0.0000001);
117 assertEquals(12.0, term(3, 2).eval(2.0), 0.0000001);
118 assertEquals(-16.0, term(-2, 3).eval(2.0), 0.0000001);
119 assertEquals(-3.0, term(3, 3).eval(-1.0), 0.0000001);
120 assertEquals(1.0, term(-1, 1).eval(-1.0), 0.0000001);
121 assertEquals(2.0, term(1, 2, 2).eval(2.0), 0.0000001);
122 assertEquals(.125, term(1, 2, 2).eval(.5), 0.0000001);
123
124 // To understand the use of "new Double(Double.NaN)" instead of
125 // "Double.NaN", see the Javadoc for Double.equals().
126 assertEquals(new Double(Double.NaN),
127 new Double(term(3, 0, 2).eval(1.0)));
128 }
129
130 @Test
131 public void testEquals() {
132 assertEquals(term(3, 5), term(3, 5));
133 assertEquals(term(1, 2, 4), term(1, 2, 4));
134 assertEquals(term(-2, 4, 2), term(1, -2, 2));
135 assertThat(term(4, 6), not(term(7, 8)));
136 }
137
138 @Test
139 public void testEqualsZeroCoeff() {
140 assertEquals(term(0, 0), term(0, 0));
141 assertEquals(term(0, 1), term(0, 0));
142 assertThat(term(0, 0), not(term(3, 5)));
143 }
144
145 @Test
146 public void testEqualsNaNCoeff() {
147 assertEquals(nanTerm, term(19, 0, 0));
148 assertEquals(nanTerm, term(0, 0, 0));
149 assertThat(nanTerm, not(term(3, 5)));
150 assertThat(term(0, 3), not(nanTerm));
151 }
152
153 // All tests below depend on constructor and equals.
154
155 // ValueOf tests
156
157 private void testValueOf(String actual, RatTerm target) {
158 assertEquals(target, RatTerm.valueOf(actual));
159 }
160
161 @Test
162 public void testValueOfSimple() {
163 testValueOf("x", term(1, 1));
164 testValueOf("-x", term(-1, 1));
165 }
166
167 @Test
168 public void testValueOfConst() {
169 testValueOf("2", term(2, 0));
170 testValueOf("3/4", term(3, 4, 0));
171 testValueOf("-4", term(-4, 0));
172 testValueOf("-7/5", term(-7, 5, 0));
173 }
174
175 @Test
176 public void testValueOfLeadingCoeff() {
177 testValueOf("2*x", term(2, 1));
178 testValueOf("3/7*x", term(3, 7, 1));
179 testValueOf("-4/3*x", term(-4, 3, 1));
180 }
181
182 @Test
183 public void testValueOfPow() {
184 testValueOf("x^3", term(1, 3));
185 testValueOf("-x^4", term(-1, 4));
186 }
187
188 @Test
189 public void testValueOfFull() {
190 testValueOf("4*x^2", term(4, 2));
191 testValueOf("2/5*x^6", term(2, 5, 6));
192 testValueOf("-3/2*x^2", term(-3, 2, 2));
193 }
194
195 @Test
196 public void testValueOfNaN() {
197 testValueOf("NaN", term(1, 0, 0));
198 }
199
200 @Test
201 public void testValueOfZero() {
202 testValueOf("0", term(0, 0));
203 }
204
205 // toString tests
206
207 private void testToString(String target, RatTerm actual) {
208 assertEquals(target, actual.toString());
209 }
210
211 @Test
212 public void testToStringSimple() {
213 testToString("x", term(1, 1));
214 testToString("-x", term(-1, 1));
215 }
216
217 @Test
218 public void testToStringConst() {
219 testToString("2", term(2, 0));
220 testToString("3/4", term(3, 4, 0));
221 testToString("-4", term(-4, 0));
222 testToString("-7/5", term(-7, 5, 0));
223 }
224
225 @Test
226 public void testToStringLeadingCoeff() {
227 testToString("2*x", term(2, 1));
228 testToString("3/7*x", term(3, 7, 1));
229 testToString("-4/3*x", term(-4, 3, 1));
230 }
231
232 @Test
233 public void testToStringPow() {
234 testToString("x^3", term(1, 3));
235 testToString("-x^4", term(-1, 4));
236 }
237
238 @Test
239 public void testToStringFull() {
240 testToString("4*x^2", term(4, 2));
241 testToString("2/5*x^6", term(2, 5, 6));
242 testToString("-3/2*x^2", term(-3, 2, 2));
243 }
244
245 @Test
246 public void testToStringNaN() {
247 testToString("NaN", term(1, 0, 0));
248 }
249
250 @Test
251 public void testToStringZero() {
252 testToString("0", term(0, 0));
253 }
254
255 // Operation tests
256 // Tests involving NaN and zero are given separately at end
257 @Test
258 public void testAdd() {
259 assertEquals(term(3, 0), term(1, 0).add(term(2, 0)));
260 assertEquals(term(4, 2), term(3, 2).add(term(1, 2)));
261 assertEquals(term(1, 2, 3), term(1, 6, 3).add(term(1, 3, 3)));
262 assertEquals(term(1, 8, 1), term(1, 4, 1).add(term(-1, 8, 1)));
263 assertEquals(term(-1, 8, 1), term(-1, 4, 1).add(term(1, 8, 1)));
264 }
265
266 @Test
267 public void testSub() {
268 assertEquals(term(1, 0), term(2, 0).sub(term(1, 0)));
269 assertEquals(term(-1, 0), term(1, 0).sub(term(2, 0)));
270 assertEquals(term(2, 2), term(3, 2).sub(term(1, 2)));
271 assertEquals(term(-1, 6, 3), term(1, 6, 3).sub(term(1, 3, 3)));
272 assertEquals(term(3, 8, 1), term(1, 4, 1).sub(term(-1, 8, 1)));
273 assertEquals(term(-3, 8, 1), term(-1, 4, 1).sub(term(1, 8, 1)));
274 }
275
276 @Test
277 public void testMul() {
278 assertEquals(term(2, 0), term(1, 0).mul(term(2, 0)));
279 assertEquals(term(3, 4), term(3, 2).mul(term(1, 2)));
280 assertEquals(term(1, 18, 6), term(1, 6, 3).mul(term(1, 3, 3)));
281 assertEquals(term(-1, 32, 2), term(1, 4, 1).mul(term(-1, 8, 1)));
282 assertEquals(term(2, 1), term(2, 1).mul(term(1, 0)));
283 }
284
285 @Test
286 public void testDiv() {
287 assertEquals(term(1, 2, 0), term(1, 0).div(term(2, 0)));
288 assertEquals(term(3, 0), term(3, 2).div(term(1, 2)));
289 assertEquals(term(1, 2, 0), term(1, 6, 3).div(term(1, 3, 3)));
290 assertEquals(term(-2, 0), term(1, 4, 1).div(term(-1, 8, 1)));
291 assertEquals(term(2, 1), term(2, 1).div(term(1, 0)));
292 assertEquals(term(8, 3), term(-16, 5).div(term(-2, 2)));
293 }
294
295 @Test
296 public void testOperationsOnNaN() {
297 assertEquals(nanTerm, nanTerm.add(term(3, 4)));
298 assertEquals(nanTerm, term(3, 4).add(nanTerm));
299 assertEquals(nanTerm, nanTerm.sub(term(3, 4)));
300 assertEquals(nanTerm, term(3, 4).sub(nanTerm));
301 assertEquals(nanTerm, nanTerm.mul(term(3, 4)));
302 assertEquals(nanTerm, term(3, 4).mul(nanTerm));
303 assertEquals(nanTerm, nanTerm.div(term(3, 4)));
304 assertEquals(nanTerm, term(3, 4).div(nanTerm));
305 }
306
307 @Test
308 public void testOperationsOnZero() {
309 RatTerm t = term(-2, 3);
310 RatTerm zero = term(0, 0);
311 assertEquals(t, zero.add(t));
312 assertEquals(t, t.add(zero));
313 assertEquals(term(2, 3), zero.sub(t));
314 assertEquals(t, t.sub(zero));
315 assertEquals(zero, zero.mul(t));
316 assertEquals(zero, t.mul(zero));
317 assertEquals(zero, zero.div(t));
318 assertEquals(nanTerm, t.div(zero));
319 assertEquals(0, t.sub(t).getExpt());
320 }
321
322 // add and sub should disallow non-zero arguments that differ in
323 // exponent.
324 @Test
325 public void testDifferentExptArgs() {
326 assertTrue(addDifferentExpts(term(1, 2), term(1, 4)));
327 assertTrue(addDifferentExpts(term(3, 2, 0), term(7, 3, 1)));
328 assertTrue(subDifferentExpts(term(1, 2), term(1, 4)));
329 assertTrue(subDifferentExpts(term(3, 2, 0), term(7, 3, 1)));
330 }
331
332 // test helper method
333 private boolean addDifferentExpts(RatTerm arg1, RatTerm arg2) {
334 try {
335 arg1.add(arg2);
336 // Should not have reached this line:
337 // cannot allow adding non-zero RatTerms of different exponents
338 return false;
339 } catch (IllegalArgumentException e) {
340 return true;
341 }
342 }
343
344 // test helper method
345 private boolean subDifferentExpts(RatTerm arg1, RatTerm arg2) {
346 try {
347 arg1.sub(arg2);
348 // Should not have reached this line:
349 // cannot allow adding non-zero RatTerms of different exponents
350 return false;
351 } catch (IllegalArgumentException e) {
352 return true;
353 }
354 }
355
356 @Test
357 public void testDifferentiate() {
358 assertEquals(term(1, 0), term(1, 1).differentiate());
359 assertEquals(term(0, 0), term(99, 0).differentiate());
360 assertEquals(term(5, 0), term(5, 1).differentiate());
361 assertEquals(term(14, 1), term(7, 2).differentiate());
362 assertEquals(term(-2, 3), term(-1, 2, 4).differentiate());
363 assertEquals(nanTerm, nanTerm.differentiate());
364 assertEquals(nanTerm, (new RatTerm(RatNum.NaN, 0)).differentiate());
365 }
366
367 @Test
368 public void testAntiDifferentiate() {
369 assertEquals(term(1, 1), term(1, 0).antiDifferentiate());
370 assertEquals(term(1, 2), term(2, 1).antiDifferentiate());
371 assertEquals(term(4, 3, 3), term(4, 2).antiDifferentiate());
372 assertEquals(nanTerm, nanTerm.antiDifferentiate());
373 }
374
375 }