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