View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.linear;
23  
24  import org.hipparchus.exception.MathIllegalArgumentException;
25  import org.hipparchus.fraction.Fraction;
26  import org.hipparchus.fraction.FractionField;
27  import org.junit.jupiter.api.Test;
28  
29  import java.util.Arrays;
30  
31  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
32  import static org.junit.jupiter.api.Assertions.assertEquals;
33  import static org.junit.jupiter.api.Assertions.assertNotSame;
34  import static org.junit.jupiter.api.Assertions.assertSame;
35  import static org.junit.jupiter.api.Assertions.assertTrue;
36  import static org.junit.jupiter.api.Assertions.fail;
37  
38  
39  /**
40   * Test cases for the {@link SparseFieldVector} class.
41   *
42   */
43  class SparseFieldVectorTest {
44  
45      //
46      protected Fraction[][] ma1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)}, {new Fraction(7), new Fraction(8), new Fraction(9)}};
47      protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)};
48      protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)};
49      protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)};
50      protected Fraction[] vec4 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(9)};
51      protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)};
52      protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7), new Fraction(8),new Fraction(9)};
53      protected Fraction[][] mat1 = {{new Fraction(1), new Fraction(2), new Fraction(3)}, {new Fraction(4), new Fraction(5), new Fraction(6)},{ new Fraction(7), new Fraction(8), new Fraction(9)}};
54  
55      // tolerances
56      protected double entryTolerance = 10E-16;
57      protected double normTolerance = 10E-14;
58  
59      protected FractionField field = FractionField.getInstance();
60  
61      @Test
62      void testMapFunctions() {
63          SparseFieldVector<Fraction> v1 = new SparseFieldVector<Fraction>(field,vec1);
64  
65          //octave =  v1 .+ 2.0
66          FieldVector<Fraction> v_mapAdd = v1.mapAdd(new Fraction(2));
67          Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)};
68          assertArrayEquals(result_mapAdd,v_mapAdd.toArray(),"compare vectors");
69  
70          //octave =  v1 .+ 2.0
71          FieldVector<Fraction> v_mapAddToSelf = v1.copy();
72          v_mapAddToSelf.mapAddToSelf(new Fraction(2));
73          Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)};
74          assertArrayEquals(result_mapAddToSelf,v_mapAddToSelf.toArray(),"compare vectors");
75  
76          //octave =  v1 .- 2.0
77          FieldVector<Fraction> v_mapSubtract = v1.mapSubtract(new Fraction(2));
78          Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)};
79          assertArrayEquals(result_mapSubtract,v_mapSubtract.toArray(),"compare vectors");
80  
81          //octave =  v1 .- 2.0
82          FieldVector<Fraction> v_mapSubtractToSelf = v1.copy();
83          v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2));
84          Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)};
85          assertArrayEquals(result_mapSubtractToSelf,v_mapSubtractToSelf.toArray(),"compare vectors");
86  
87          //octave =  v1 .* 2.0
88          FieldVector<Fraction> v_mapMultiply = v1.mapMultiply(new Fraction(2));
89          Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)};
90          assertArrayEquals(result_mapMultiply,v_mapMultiply.toArray(),"compare vectors");
91  
92          //octave =  v1 .* 2.0
93          FieldVector<Fraction> v_mapMultiplyToSelf = v1.copy();
94          v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2));
95          Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)};
96          assertArrayEquals(result_mapMultiplyToSelf,v_mapMultiplyToSelf.toArray(),"compare vectors");
97  
98          //octave =  v1 ./ 2.0
99          FieldVector<Fraction> v_mapDivide = v1.mapDivide(new Fraction(2));
100         Fraction[] result_mapDivide = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)};
101         assertArrayEquals(result_mapDivide,v_mapDivide.toArray(),"compare vectors");
102 
103         //octave =  v1 ./ 2.0
104         FieldVector<Fraction> v_mapDivideToSelf = v1.copy();
105         v_mapDivideToSelf.mapDivideToSelf(new Fraction(2));
106         Fraction[] result_mapDivideToSelf = {new Fraction(.5d), new Fraction(1), new Fraction(1.5d)};
107         assertArrayEquals(result_mapDivideToSelf,v_mapDivideToSelf.toArray(),"compare vectors");
108 
109         //octave =  v1 .^-1
110         FieldVector<Fraction> v_mapInv = v1.mapInv();
111         Fraction[] result_mapInv = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)};
112         assertArrayEquals(result_mapInv,v_mapInv.toArray(),"compare vectors");
113 
114         //octave =  v1 .^-1
115         FieldVector<Fraction> v_mapInvToSelf = v1.copy();
116         v_mapInvToSelf.mapInvToSelf();
117         Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(0.5d),new Fraction(3.333333333333333e-01d)};
118         assertArrayEquals(result_mapInvToSelf,v_mapInvToSelf.toArray(),"compare vectors");
119 
120 
121     }
122 
123     @Test
124     void testBasicFunctions() {
125         SparseFieldVector<Fraction> v1 = (SparseFieldVector<Fraction>) new SparseFieldVector<>(field).append(new SparseFieldVector<>(field,vec1));
126         SparseFieldVector<Fraction> v2 = (SparseFieldVector<Fraction>) new SparseFieldVector<>(field).append(new ArrayFieldVector<>(vec2));
127 
128         assertSame(field, v1.getField());
129         FieldVector<Fraction> v2_t = new ArrayFieldVectorTest.FieldVectorTestImpl<Fraction>(vec2);
130 
131         //octave =  v1 + v2
132         FieldVector<Fraction> v_add = v1.add(v2);
133         Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)};
134         assertArrayEquals(v_add.toArray(),result_add,"compare vect");
135 
136         FieldVector<Fraction> vt2 = new ArrayFieldVectorTest.FieldVectorTestImpl<Fraction>(vec2);
137         FieldVector<Fraction> v_add_i = v1.add(vt2);
138         Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)};
139         assertArrayEquals(v_add_i.toArray(),result_add_i,"compare vect");
140 
141         //octave =  v1 - v2
142         SparseFieldVector<Fraction> v_subtract = v1.subtract(v2);
143         Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
144         customAssertClose("compare vect" , v_subtract.toArray(), result_subtract, normTolerance);
145 
146         FieldVector<Fraction> v_subtract_i = v1.subtract(vt2);
147         Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
148         customAssertClose("compare vect" , v_subtract_i.toArray(), result_subtract_i, normTolerance);
149 
150         // octave v1 .* v2
151         FieldVector<Fraction>  v_ebeMultiply = v1.ebeMultiply(v2);
152         Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)};
153         customAssertClose("compare vect" , v_ebeMultiply.toArray(), result_ebeMultiply, normTolerance);
154 
155         FieldVector<Fraction>  v_ebeMultiply_2 = v1.ebeMultiply(v2_t);
156         Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)};
157         customAssertClose("compare vect" , v_ebeMultiply_2.toArray(), result_ebeMultiply_2, normTolerance);
158 
159         // octave v1 ./ v2
160         FieldVector<Fraction>  v_ebeDivide = v1.ebeDivide(v2);
161         Fraction[] result_ebeDivide = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)};
162         customAssertClose("compare vect" , v_ebeDivide.toArray(), result_ebeDivide, normTolerance);
163 
164         FieldVector<Fraction>  v_ebeDivide_2 = v1.ebeDivide(v2_t);
165         Fraction[] result_ebeDivide_2 = {new Fraction(0.25d), new Fraction(0.4d), new Fraction(0.5d)};
166         customAssertClose("compare vect" , v_ebeDivide_2.toArray(), result_ebeDivide_2, normTolerance);
167 
168         // octave  dot(v1,v2)
169         Fraction dot =  v1.dotProduct(v2);
170         assertEquals(new Fraction(32), dot, "compare val ");
171 
172         // octave  dot(v1,v2_t)
173         Fraction dot_2 =  v1.dotProduct(v2_t);
174         assertEquals(new Fraction(32), dot_2, "compare val ");
175 
176         FieldMatrix<Fraction> m_outerProduct = v1.outerProduct(v2);
177         assertEquals(new Fraction(4), m_outerProduct.getEntry(0,0), "compare val ");
178 
179         FieldMatrix<Fraction> m_outerProduct_2 = v1.outerProduct(v2_t);
180         assertEquals(new Fraction(4), m_outerProduct_2.getEntry(0,0), "compare val ");
181 
182     }
183 
184     @Test
185     void testOuterProduct() {
186         final SparseFieldVector<Fraction> u
187             = (SparseFieldVector<Fraction>) new SparseFieldVector<>(FractionField.getInstance(),
188                                                                     new Fraction[] { new Fraction(1),
189                                                                                      new Fraction(2) }).
190                                             append(new Fraction(-3));
191         final SparseFieldVector<Fraction> v
192             = new SparseFieldVector<Fraction>(FractionField.getInstance(),
193                                               new Fraction[] {new Fraction(4),
194                                                               new Fraction(-2)});
195 
196         final FieldMatrix<Fraction> uv = u.outerProduct(v);
197 
198         final double tol = Math.ulp(1d);
199         assertEquals(new Fraction(4).doubleValue(), uv.getEntry(0, 0).doubleValue(), tol);
200         assertEquals(new Fraction(-2).doubleValue(), uv.getEntry(0, 1).doubleValue(), tol);
201         assertEquals(new Fraction(8).doubleValue(), uv.getEntry(1, 0).doubleValue(), tol);
202         assertEquals(new Fraction(-4).doubleValue(), uv.getEntry(1, 1).doubleValue(), tol);
203         assertEquals(new Fraction(-12).doubleValue(), uv.getEntry(2, 0).doubleValue(), tol);
204         assertEquals(new Fraction(6).doubleValue(), uv.getEntry(2, 1).doubleValue(), tol);
205     }
206 
207     @Test
208     void testMisc() {
209         SparseFieldVector<Fraction> v1 = new SparseFieldVector<Fraction>(field,vec1);
210 
211         String out1 = v1.toString();
212         assertTrue(out1.length()!=0,  "some output ");
213         try {
214             v1.checkVectorDimensions(2);
215             fail("MathIllegalArgumentException expected");
216         } catch (MathIllegalArgumentException ex) {
217             // expected behavior
218         }
219 
220 
221     }
222 
223     @Test
224     void testPredicates() {
225 
226         SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) });
227 
228         v.setEntry(0, field.getZero());
229         assertEquals(v, new SparseFieldVector<Fraction>(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2) }));
230         assertNotSame(v, new SparseFieldVector<Fraction>(field, new Fraction[] { new Fraction(0), new Fraction(1), new Fraction(2), new Fraction(3) }));
231 
232     }
233 
234     /** verifies that two vectors are close (sup norm) */
235     protected void customAssertEquals(String msg, Fraction[] m, Fraction[] n) {
236         if (m.length != n.length) {
237             fail("vectors have different lengths");
238         }
239         for (int i = 0; i < m.length; i++) {
240             assertEquals(m[i],n[i],msg + " " +  i + " elements differ");
241         }
242     }
243 
244     /** verifies that two vectors are close (sup norm) */
245     protected void customAssertClose(String msg, Fraction[] m, Fraction[] n, double tolerance) {
246         if (m.length != n.length) {
247             fail("vectors have different lengths");
248         }
249         for (int i = 0; i < m.length; i++) {
250             assertEquals(m[i].doubleValue(),n[i].doubleValue(), tolerance, msg + " " +  i + " elements differ");
251         }
252     }
253 
254     /*
255      * TESTS OF THE VISITOR PATTERN
256      */
257 
258     /** The whole vector is visited. */
259     @Test
260     void testWalkInDefaultOrderPreservingVisitor1() {
261         final Fraction[] data = new Fraction[] {
262             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
263             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
264             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
265         };
266         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
267         final FieldVectorPreservingVisitor<Fraction> visitor;
268         visitor = new FieldVectorPreservingVisitor<Fraction>() {
269 
270             private int expectedIndex;
271 
272             public void visit(final int actualIndex, final Fraction actualValue) {
273                 assertEquals(expectedIndex, actualIndex);
274                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
275                 ++expectedIndex;
276             }
277 
278             public void start(final int actualSize, final int actualStart,
279                               final int actualEnd) {
280                 assertEquals(data.length, actualSize);
281                 assertEquals(0, actualStart);
282                 assertEquals(data.length - 1, actualEnd);
283                 expectedIndex = 0;
284             }
285 
286             public Fraction end() {
287                 return Fraction.ZERO;
288             }
289         };
290         v.walkInDefaultOrder(visitor);
291     }
292 
293     /** Visiting an invalid subvector. */
294     @Test
295     void testWalkInDefaultOrderPreservingVisitor2() {
296         final SparseFieldVector<Fraction> v = create(5);
297         final FieldVectorPreservingVisitor<Fraction> visitor;
298         visitor = new FieldVectorPreservingVisitor<Fraction>() {
299 
300             public void visit(int index, Fraction value) {
301                 // Do nothing
302             }
303 
304             public void start(int dimension, int start, int end) {
305                 // Do nothing
306             }
307 
308             public Fraction end() {
309                 return Fraction.ZERO;
310             }
311         };
312         try {
313             v.walkInDefaultOrder(visitor, -1, 4);
314             fail();
315         } catch (MathIllegalArgumentException e) {
316             // Expected behavior
317         }
318         try {
319             v.walkInDefaultOrder(visitor, 5, 4);
320             fail();
321         } catch (MathIllegalArgumentException e) {
322             // Expected behavior
323         }
324         try {
325             v.walkInDefaultOrder(visitor, 0, -1);
326             fail();
327         } catch (MathIllegalArgumentException e) {
328             // Expected behavior
329         }
330         try {
331             v.walkInDefaultOrder(visitor, 0, 5);
332             fail();
333         } catch (MathIllegalArgumentException e) {
334             // Expected behavior
335         }
336         try {
337             v.walkInDefaultOrder(visitor, 4, 0);
338             fail();
339         } catch (MathIllegalArgumentException e) {
340             // Expected behavior
341         }
342     }
343 
344     /** Visiting a valid subvector. */
345     @Test
346     void testWalkInDefaultOrderPreservingVisitor3() {
347         final Fraction[] data = new Fraction[] {
348             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
349             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
350             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
351         };
352         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
353         final int expectedStart = 2;
354         final int expectedEnd = 7;
355         final FieldVectorPreservingVisitor<Fraction> visitor;
356         visitor = new FieldVectorPreservingVisitor<Fraction>() {
357 
358             private int expectedIndex;
359 
360             public void visit(final int actualIndex, final Fraction actualValue) {
361                 assertEquals(expectedIndex, actualIndex);
362                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
363                 ++expectedIndex;
364             }
365 
366             public void start(final int actualSize, final int actualStart,
367                               final int actualEnd) {
368                 assertEquals(data.length, actualSize);
369                 assertEquals(expectedStart, actualStart);
370                 assertEquals(expectedEnd, actualEnd);
371                 expectedIndex = expectedStart;
372             }
373 
374             public Fraction end() {
375                 return Fraction.ZERO;
376             }
377         };
378         v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
379     }
380 
381     /** The whole vector is visited. */
382     @Test
383     void testWalkInOptimizedOrderPreservingVisitor1() {
384         final Fraction[] data = new Fraction[] {
385             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
386             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
387             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
388         };
389         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
390         final FieldVectorPreservingVisitor<Fraction> visitor;
391         visitor = new FieldVectorPreservingVisitor<Fraction>() {
392             private final boolean[] visited = new boolean[data.length];
393 
394             public void visit(final int actualIndex, final Fraction actualValue) {
395                 visited[actualIndex] = true;
396                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
397             }
398 
399             public void start(final int actualSize, final int actualStart,
400                               final int actualEnd) {
401                 assertEquals(data.length, actualSize);
402                 assertEquals(0, actualStart);
403                 assertEquals(data.length - 1, actualEnd);
404                 Arrays.fill(visited, false);
405             }
406 
407             public Fraction end() {
408                 for (int i = 0; i < data.length; i++) {
409                     assertTrue(visited[i],
410                                       "entry " + i + "has not been visited");
411                 }
412                 return Fraction.ZERO;
413             }
414         };
415         v.walkInOptimizedOrder(visitor);
416     }
417 
418     /** Visiting an invalid subvector. */
419     @Test
420     void testWalkInOptimizedOrderPreservingVisitor2() {
421         final SparseFieldVector<Fraction> v = create(5);
422         final FieldVectorPreservingVisitor<Fraction> visitor;
423         visitor = new FieldVectorPreservingVisitor<Fraction>() {
424 
425             public void visit(int index, Fraction value) {
426                 // Do nothing
427             }
428 
429             public void start(int dimension, int start, int end) {
430                 // Do nothing
431             }
432 
433             public Fraction end() {
434                 return Fraction.ZERO;
435             }
436         };
437         try {
438             v.walkInOptimizedOrder(visitor, -1, 4);
439             fail();
440         } catch (MathIllegalArgumentException e) {
441             // Expected behavior
442         }
443         try {
444             v.walkInOptimizedOrder(visitor, 5, 4);
445             fail();
446         } catch (MathIllegalArgumentException e) {
447             // Expected behavior
448         }
449         try {
450             v.walkInOptimizedOrder(visitor, 0, -1);
451             fail();
452         } catch (MathIllegalArgumentException e) {
453             // Expected behavior
454         }
455         try {
456             v.walkInOptimizedOrder(visitor, 0, 5);
457             fail();
458         } catch (MathIllegalArgumentException e) {
459             // Expected behavior
460         }
461         try {
462             v.walkInOptimizedOrder(visitor, 4, 0);
463             fail();
464         } catch (MathIllegalArgumentException e) {
465             // Expected behavior
466         }
467     }
468 
469     /** Visiting a valid subvector. */
470     @Test
471     void testWalkInOptimizedOrderPreservingVisitor3() {
472         final Fraction[] data = new Fraction[] {
473             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
474             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
475             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
476         };
477         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
478         final int expectedStart = 2;
479         final int expectedEnd = 7;
480         final FieldVectorPreservingVisitor<Fraction> visitor;
481         visitor = new FieldVectorPreservingVisitor<Fraction>() {
482             private final boolean[] visited = new boolean[data.length];
483 
484             public void visit(final int actualIndex, final Fraction actualValue) {
485                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
486                 visited[actualIndex] = true;
487             }
488 
489             public void start(final int actualSize, final int actualStart,
490                               final int actualEnd) {
491                 assertEquals(data.length, actualSize);
492                 assertEquals(expectedStart, actualStart);
493                 assertEquals(expectedEnd, actualEnd);
494                 Arrays.fill(visited, true);
495             }
496 
497             public Fraction end() {
498                 for (int i = expectedStart; i <= expectedEnd; i++) {
499                     assertTrue(visited[i],
500                                       "entry " + i + "has not been visited");
501                 }
502                 return Fraction.ZERO;
503             }
504         };
505         v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
506     }
507 
508     /** The whole vector is visited. */
509     @Test
510     void testWalkInDefaultOrderChangingVisitor1() {
511         final Fraction[] data = new Fraction[] {
512             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
513             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
514             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
515         };
516         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
517         final FieldVectorChangingVisitor<Fraction> visitor;
518         visitor = new FieldVectorChangingVisitor<Fraction>() {
519 
520             private int expectedIndex;
521 
522             public Fraction visit(final int actualIndex, final Fraction actualValue) {
523                 assertEquals(expectedIndex, actualIndex);
524                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
525                 ++expectedIndex;
526                 return actualValue.add(actualIndex);
527             }
528 
529             public void start(final int actualSize, final int actualStart,
530                               final int actualEnd) {
531                 assertEquals(data.length, actualSize);
532                 assertEquals(0, actualStart);
533                 assertEquals(data.length - 1, actualEnd);
534                 expectedIndex = 0;
535             }
536 
537             public Fraction end() {
538                 return Fraction.ZERO;
539             }
540         };
541         v.walkInDefaultOrder(visitor);
542         for (int i = 0; i < data.length; i++) {
543             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
544         }
545     }
546 
547     /** Visiting an invalid subvector. */
548     @Test
549     void testWalkInDefaultOrderChangingVisitor2() {
550         final SparseFieldVector<Fraction> v = create(5);
551         final FieldVectorChangingVisitor<Fraction> visitor;
552         visitor = new FieldVectorChangingVisitor<Fraction>() {
553 
554             public Fraction visit(int index, Fraction value) {
555                 return Fraction.ZERO;
556             }
557 
558             public void start(int dimension, int start, int end) {
559                 // Do nothing
560             }
561 
562             public Fraction end() {
563                 return Fraction.ZERO;
564             }
565         };
566         try {
567             v.walkInDefaultOrder(visitor, -1, 4);
568             fail();
569         } catch (MathIllegalArgumentException e) {
570             // Expected behavior
571         }
572         try {
573             v.walkInDefaultOrder(visitor, 5, 4);
574             fail();
575         } catch (MathIllegalArgumentException e) {
576             // Expected behavior
577         }
578         try {
579             v.walkInDefaultOrder(visitor, 0, -1);
580             fail();
581         } catch (MathIllegalArgumentException e) {
582             // Expected behavior
583         }
584         try {
585             v.walkInDefaultOrder(visitor, 0, 5);
586             fail();
587         } catch (MathIllegalArgumentException e) {
588             // Expected behavior
589         }
590         try {
591             v.walkInDefaultOrder(visitor, 4, 0);
592             fail();
593         } catch (MathIllegalArgumentException e) {
594             // Expected behavior
595         }
596     }
597 
598     /** Visiting a valid subvector. */
599     @Test
600     void testWalkInDefaultOrderChangingVisitor3() {
601         final Fraction[] data = new Fraction[] {
602             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
603             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
604             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
605         };
606         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
607         final int expectedStart = 2;
608         final int expectedEnd = 7;
609         final FieldVectorChangingVisitor<Fraction> visitor;
610         visitor = new FieldVectorChangingVisitor<Fraction>() {
611 
612             private int expectedIndex;
613 
614             public Fraction visit(final int actualIndex, final Fraction actualValue) {
615                 assertEquals(expectedIndex, actualIndex);
616                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
617                 ++expectedIndex;
618                 return actualValue.add(actualIndex);
619             }
620 
621             public void start(final int actualSize, final int actualStart,
622                               final int actualEnd) {
623                 assertEquals(data.length, actualSize);
624                 assertEquals(expectedStart, actualStart);
625                 assertEquals(expectedEnd, actualEnd);
626                 expectedIndex = expectedStart;
627             }
628 
629             public Fraction end() {
630                 return Fraction.ZERO;
631             }
632         };
633         v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
634         for (int i = expectedStart; i <= expectedEnd; i++) {
635             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
636         }
637     }
638 
639     /** The whole vector is visited. */
640     @Test
641     void testWalkInOptimizedOrderChangingVisitor1() {
642         final Fraction[] data = new Fraction[] {
643             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
644             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
645             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
646         };
647         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
648         final FieldVectorChangingVisitor<Fraction> visitor;
649         visitor = new FieldVectorChangingVisitor<Fraction>() {
650             private final boolean[] visited = new boolean[data.length];
651 
652             public Fraction visit(final int actualIndex, final Fraction actualValue) {
653                 visited[actualIndex] = true;
654                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
655                 return actualValue.add(actualIndex);
656             }
657 
658             public void start(final int actualSize, final int actualStart,
659                               final int actualEnd) {
660                 assertEquals(data.length, actualSize);
661                 assertEquals(0, actualStart);
662                 assertEquals(data.length - 1, actualEnd);
663                 Arrays.fill(visited, false);
664             }
665 
666             public Fraction end() {
667                 for (int i = 0; i < data.length; i++) {
668                     assertTrue(visited[i],
669                                       "entry " + i + "has not been visited");
670                 }
671                 return Fraction.ZERO;
672             }
673         };
674         v.walkInOptimizedOrder(visitor);
675         for (int i = 0; i < data.length; i++) {
676             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
677         }
678     }
679 
680     /** Visiting an invalid subvector. */
681     @Test
682     void testWalkInOptimizedOrderChangingVisitor2() {
683         final SparseFieldVector<Fraction> v = create(5);
684         final FieldVectorChangingVisitor<Fraction> visitor;
685         visitor = new FieldVectorChangingVisitor<Fraction>() {
686 
687             public Fraction visit(int index, Fraction value) {
688                 return Fraction.ZERO;
689             }
690 
691             public void start(int dimension, int start, int end) {
692                 // Do nothing
693             }
694 
695             public Fraction end() {
696                 return Fraction.ZERO;
697             }
698         };
699         try {
700             v.walkInOptimizedOrder(visitor, -1, 4);
701             fail();
702         } catch (MathIllegalArgumentException e) {
703             // Expected behavior
704         }
705         try {
706             v.walkInOptimizedOrder(visitor, 5, 4);
707             fail();
708         } catch (MathIllegalArgumentException e) {
709             // Expected behavior
710         }
711         try {
712             v.walkInOptimizedOrder(visitor, 0, -1);
713             fail();
714         } catch (MathIllegalArgumentException e) {
715             // Expected behavior
716         }
717         try {
718             v.walkInOptimizedOrder(visitor, 0, 5);
719             fail();
720         } catch (MathIllegalArgumentException e) {
721             // Expected behavior
722         }
723         try {
724             v.walkInOptimizedOrder(visitor, 4, 0);
725             fail();
726         } catch (MathIllegalArgumentException e) {
727             // Expected behavior
728         }
729     }
730 
731     /** Visiting a valid subvector. */
732     @Test
733     void testWalkInOptimizedOrderChangingVisitor3() {
734         final Fraction[] data = new Fraction[] {
735             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
736             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
737             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
738         };
739         final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
740         final int expectedStart = 2;
741         final int expectedEnd = 7;
742         final FieldVectorChangingVisitor<Fraction> visitor;
743         visitor = new FieldVectorChangingVisitor<Fraction>() {
744             private final boolean[] visited = new boolean[data.length];
745 
746             public Fraction visit(final int actualIndex, final Fraction actualValue) {
747                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
748                 visited[actualIndex] = true;
749                 return actualValue.add(actualIndex);
750             }
751 
752             public void start(final int actualSize, final int actualStart,
753                               final int actualEnd) {
754                 assertEquals(data.length, actualSize);
755                 assertEquals(expectedStart, actualStart);
756                 assertEquals(expectedEnd, actualEnd);
757                 Arrays.fill(visited, true);
758             }
759 
760             public Fraction end() {
761                 for (int i = expectedStart; i <= expectedEnd; i++) {
762                     assertTrue(visited[i],
763                                       "entry " + i + "has not been visited");
764                 }
765                 return Fraction.ZERO;
766             }
767         };
768         v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
769         for (int i = expectedStart; i <= expectedEnd; i++) {
770             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
771         }
772     }
773 
774     private SparseFieldVector<Fraction> create(int n) {
775         Fraction[] t = new Fraction[n];
776         for (int i = 0; i < n; ++i) {
777             t[i] = Fraction.ZERO;
778         }
779         return new SparseFieldVector<Fraction>(field, t);
780     }
781 }