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