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