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.Field;
25  import org.hipparchus.FieldElement;
26  import org.hipparchus.UnitTestUtils;
27  import org.hipparchus.exception.MathIllegalArgumentException;
28  import org.hipparchus.fraction.Fraction;
29  import org.hipparchus.fraction.FractionField;
30  import org.junit.jupiter.api.Test;
31  
32  import java.io.Serializable;
33  import java.lang.reflect.Array;
34  import java.util.Arrays;
35  
36  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
37  import static org.junit.jupiter.api.Assertions.assertEquals;
38  import static org.junit.jupiter.api.Assertions.assertNotSame;
39  import static org.junit.jupiter.api.Assertions.assertTrue;
40  import static org.junit.jupiter.api.Assertions.fail;
41  
42  /**
43   * Test cases for the {@link ArrayFieldVector} class.
44   *
45   */
46  class ArrayFieldVectorTest {
47  
48      //
49      protected Fraction[][] ma1 = {
50              {new Fraction(1), new Fraction(2), new Fraction(3)},
51              {new Fraction(4), new Fraction(5), new Fraction(6)},
52              {new Fraction(7), new Fraction(8), new Fraction(9)}
53      };
54      protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)};
55      protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)};
56      protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)};
57      protected Fraction[] vec4 = { new Fraction(1), new Fraction(2), new Fraction(3),
58                                    new Fraction(4), new Fraction(5), new Fraction(6),
59                                    new Fraction(7), new Fraction(8), new Fraction(9)};
60      protected Fraction[] vec_null = {Fraction.ZERO, Fraction.ZERO, Fraction.ZERO};
61      protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3),
62                                    new Fraction(4), new Fraction(5), new Fraction(6),
63                                    new Fraction(7), new Fraction(8), new Fraction(9)};
64      protected Fraction[][] mat1 = {
65              {new Fraction(1), new Fraction(2), new Fraction(3)},
66              {new Fraction(4), new Fraction(5), new Fraction(6)},
67              {new Fraction(7), new Fraction(8), new Fraction(9)}
68      };
69  
70      // Testclass to test the FieldVector<Fraction> interface
71      // only with enough content to support the test
72      public static class FieldVectorTestImpl<T extends FieldElement<T>>
73          implements FieldVector<T>, Serializable {
74  
75          private static final long serialVersionUID = 3970959016014158539L;
76  
77          private final Field<T> field;
78  
79          /** Entries of the vector. */
80          protected T[] data;
81  
82          /** Build an array of elements.
83           * @param length size of the array to build
84           * @return a new array
85           */
86          @SuppressWarnings("unchecked") // field is of type T
87          private T[] buildArray(final int length) {
88              return (T[]) Array.newInstance(field.getRuntimeClass(), length);
89          }
90  
91          public FieldVectorTestImpl(T[] d) {
92              field = d[0].getField();
93              data = d.clone();
94          }
95  
96          public Field<T> getField() {
97              return field;
98          }
99  
100         private UnsupportedOperationException unsupported() {
101             return new UnsupportedOperationException("Not supported, unneeded for test purposes");
102         }
103 
104         public FieldVector<T> copy() {
105             throw unsupported();
106         }
107 
108         public FieldVector<T> add(FieldVector<T> v) {
109             throw unsupported();
110         }
111 
112         public FieldVector<T> add(T[] v) {
113             throw unsupported();
114         }
115 
116         public FieldVector<T> subtract(FieldVector<T> v) {
117             throw unsupported();
118         }
119 
120         public FieldVector<T> subtract(T[] v) {
121             throw unsupported();
122         }
123 
124         public FieldVector<T> mapAdd(T d) {
125             throw unsupported();
126         }
127 
128         public FieldVector<T> mapAddToSelf(T d) {
129             throw unsupported();
130         }
131 
132         public FieldVector<T> mapSubtract(T d) {
133             throw unsupported();
134         }
135 
136         public FieldVector<T> mapSubtractToSelf(T d) {
137             throw unsupported();
138         }
139 
140         public FieldVector<T> mapMultiply(T d) {
141             T[] out = buildArray(data.length);
142             for (int i = 0; i < data.length; i++) {
143                 out[i] = data[i].multiply(d);
144             }
145             return new FieldVectorTestImpl<T>(out);
146         }
147 
148         public FieldVector<T> mapMultiplyToSelf(T d) {
149             throw unsupported();
150         }
151 
152         public FieldVector<T> mapDivide(T d) {
153             throw unsupported();
154         }
155 
156         public FieldVector<T> mapDivideToSelf(T d) {
157             throw unsupported();
158         }
159 
160         public FieldVector<T> mapInv() {
161             throw unsupported();
162         }
163 
164         public FieldVector<T> mapInvToSelf() {
165             throw unsupported();
166         }
167 
168         public FieldVector<T> ebeMultiply(FieldVector<T> v) {
169             throw unsupported();
170         }
171 
172         public FieldVector<T> ebeMultiply(T[] v) {
173             throw unsupported();
174         }
175 
176         public FieldVector<T> ebeDivide(FieldVector<T> v) {
177             throw unsupported();
178         }
179 
180         public FieldVector<T> ebeDivide(T[] v) {
181             throw unsupported();
182         }
183 
184         public T[] getData() {
185             return data.clone();
186         }
187 
188         public T dotProduct(FieldVector<T> v) {
189             T dot = field.getZero();
190             for (int i = 0; i < data.length; i++) {
191                 dot = dot.add(data[i].multiply(v.getEntry(i)));
192             }
193             return dot;
194         }
195 
196         public T dotProduct(T[] v) {
197             T dot = field.getZero();
198             for (int i = 0; i < data.length; i++) {
199                 dot = dot.add(data[i].multiply(v[i]));
200             }
201             return dot;
202         }
203 
204         public FieldVector<T> projection(FieldVector<T> v) {
205             throw unsupported();
206         }
207 
208         public FieldVector<T> projection(T[] v) {
209             throw unsupported();
210         }
211 
212         public FieldMatrix<T> outerProduct(FieldVector<T> v) {
213             throw unsupported();
214         }
215 
216         public FieldMatrix<T> outerProduct(T[] v) {
217             throw unsupported();
218         }
219 
220         public T getEntry(int index) {
221             return data[index];
222         }
223 
224         public int getDimension() {
225             return data.length;
226         }
227 
228         public FieldVector<T> append(FieldVector<T> v) {
229             throw unsupported();
230         }
231 
232         public FieldVector<T> append(T d) {
233             throw unsupported();
234         }
235 
236         public FieldVector<T> append(T[] a) {
237             throw unsupported();
238         }
239 
240         public FieldVector<T> getSubVector(int index, int n) {
241             throw unsupported();
242         }
243 
244         public void setEntry(int index, T value) {
245             throw unsupported();
246         }
247 
248         public void setSubVector(int index, FieldVector<T> v) {
249             throw unsupported();
250         }
251 
252         public void setSubVector(int index, T[] v) {
253             throw unsupported();
254         }
255 
256         public void set(T value) {
257             throw unsupported();
258         }
259 
260         public T[] toArray() {
261             return data.clone();
262         }
263 
264     }
265 
266     @Test
267     void testConstructors() {
268 
269         ArrayFieldVector<Fraction> v0 = new ArrayFieldVector<Fraction>(FractionField.getInstance());
270         assertEquals(0, v0.getDimension());
271 
272         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(FractionField.getInstance(), 7);
273         assertEquals(7, v1.getDimension());
274         assertEquals(Fraction.ZERO, v1.getEntry(6));
275 
276         ArrayFieldVector<Fraction> v2 = new ArrayFieldVector<Fraction>(5, new Fraction(123, 100));
277         assertEquals(5, v2.getDimension());
278         assertEquals(new Fraction(123, 100), v2.getEntry(4));
279 
280         ArrayFieldVector<Fraction> v3 = new ArrayFieldVector<Fraction>(FractionField.getInstance(), vec1);
281         assertEquals(3, v3.getDimension());
282         assertEquals(new Fraction(2), v3.getEntry(1));
283 
284         ArrayFieldVector<Fraction> v4 = new ArrayFieldVector<Fraction>(FractionField.getInstance(), vec4, 3, 2);
285         assertEquals(2, v4.getDimension());
286         assertEquals(new Fraction(4), v4.getEntry(0));
287         try {
288             new ArrayFieldVector<Fraction>(vec4, 8, 3);
289             fail("MathIllegalArgumentException expected");
290         } catch (MathIllegalArgumentException ex) {
291             // expected behavior
292         }
293 
294         FieldVector<Fraction> v5_i = new ArrayFieldVector<Fraction>(dvec1);
295         assertEquals(9, v5_i.getDimension());
296         assertEquals(new Fraction(9), v5_i.getEntry(8));
297 
298         ArrayFieldVector<Fraction> v5 = new ArrayFieldVector<Fraction>(dvec1);
299         assertEquals(9, v5.getDimension());
300         assertEquals(new Fraction(9), v5.getEntry(8));
301 
302         ArrayFieldVector<Fraction> v6 = new ArrayFieldVector<Fraction>(dvec1, 3, 2);
303         assertEquals(2, v6.getDimension());
304         assertEquals(new Fraction(4), v6.getEntry(0));
305         try {
306             new ArrayFieldVector<Fraction>(dvec1, 8, 3);
307             fail("MathIllegalArgumentException expected");
308         } catch (MathIllegalArgumentException ex) {
309             // expected behavior
310         }
311 
312         ArrayFieldVector<Fraction> v7 = new ArrayFieldVector<Fraction>(v1);
313         assertEquals(7, v7.getDimension());
314         assertEquals(Fraction.ZERO, v7.getEntry(6));
315 
316         FieldVectorTestImpl<Fraction> v7_i = new FieldVectorTestImpl<Fraction>(vec1);
317 
318         ArrayFieldVector<Fraction> v7_2 = new ArrayFieldVector<Fraction>(v7_i);
319         assertEquals(3, v7_2.getDimension());
320         assertEquals(new Fraction(2), v7_2.getEntry(1));
321 
322         ArrayFieldVector<Fraction> v8 = new ArrayFieldVector<Fraction>(v1, true);
323         assertEquals(7, v8.getDimension());
324         assertEquals(Fraction.ZERO, v8.getEntry(6));
325         assertNotSame(v1.getDataRef(), v8.getDataRef(), "testData not same object ");
326 
327         ArrayFieldVector<Fraction> v8_2 = new ArrayFieldVector<Fraction>(v1, false);
328         assertEquals(7, v8_2.getDimension());
329         assertEquals(Fraction.ZERO, v8_2.getEntry(6));
330         assertArrayEquals(v1.getDataRef(), v8_2.getDataRef());
331 
332         ArrayFieldVector<Fraction> v9 = new ArrayFieldVector<Fraction>((FieldVector<Fraction>) v1, (FieldVector<Fraction>) v3);
333         assertEquals(10, v9.getDimension());
334         assertEquals(new Fraction(1), v9.getEntry(7));
335 
336     }
337 
338     @Test
339     void testDataInOut() {
340 
341         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(vec1);
342         ArrayFieldVector<Fraction> v2 = new ArrayFieldVector<Fraction>(vec2);
343         ArrayFieldVector<Fraction> v4 = new ArrayFieldVector<Fraction>(vec4);
344         FieldVectorTestImpl<Fraction> v2_t = new FieldVectorTestImpl<Fraction>(vec2);
345 
346         FieldVector<Fraction> v_append_1 = v1.append(v2);
347         assertEquals(6, v_append_1.getDimension());
348         assertEquals(new Fraction(4), v_append_1.getEntry(3));
349 
350         FieldVector<Fraction> v_append_2 = v1.append(new Fraction(2));
351         assertEquals(4, v_append_2.getDimension());
352         assertEquals(new Fraction(2), v_append_2.getEntry(3));
353 
354         FieldVector<Fraction> v_append_4 = v1.append(v2_t);
355         assertEquals(6, v_append_4.getDimension());
356         assertEquals(new Fraction(4), v_append_4.getEntry(3));
357 
358         FieldVector<Fraction> v_copy = v1.copy();
359         assertEquals(3, v_copy.getDimension());
360         assertNotSame(v1.getDataRef(), v_copy.toArray(), "testData not same object ");
361 
362         Fraction[] a_frac = v1.toArray();
363         assertEquals(3, a_frac.length);
364         assertNotSame(v1.getDataRef(), a_frac, "testData not same object ");
365 
366 
367 //      ArrayFieldVector<Fraction> vout4 = (ArrayFieldVector<Fraction>) v1.clone();
368 //      Assertions.assertEquals(3, vout4.getDimension());
369 //      Assertions.assertEquals(v1.getDataRef(), vout4.getDataRef());
370 
371 
372         FieldVector<Fraction> vout5 = v4.getSubVector(3, 3);
373         assertEquals(3, vout5.getDimension());
374         assertEquals(new Fraction(5), vout5.getEntry(1));
375         try {
376             v4.getSubVector(3, 7);
377             fail("MathIllegalArgumentException expected");
378         } catch (MathIllegalArgumentException ex) {
379             // expected behavior
380         }
381 
382         ArrayFieldVector<Fraction> v_set1 = (ArrayFieldVector<Fraction>) v1.copy();
383         v_set1.setEntry(1, new Fraction(11));
384         assertEquals(new Fraction(11), v_set1.getEntry(1));
385         try {
386             v_set1.setEntry(3, new Fraction(11));
387             fail("MathIllegalArgumentException expected");
388         } catch (MathIllegalArgumentException ex) {
389             // expected behavior
390         }
391 
392         ArrayFieldVector<Fraction> v_set2 = (ArrayFieldVector<Fraction>) v4.copy();
393         v_set2.set(3, v1);
394         assertEquals(new Fraction(1), v_set2.getEntry(3));
395         assertEquals(new Fraction(7), v_set2.getEntry(6));
396         try {
397             v_set2.set(7, v1);
398             fail("MathIllegalArgumentException expected");
399         } catch (MathIllegalArgumentException ex) {
400             // expected behavior
401         }
402 
403         ArrayFieldVector<Fraction> v_set3 = (ArrayFieldVector<Fraction>) v1.copy();
404         v_set3.set(new Fraction(13));
405         assertEquals(new Fraction(13), v_set3.getEntry(2));
406 
407         try {
408             v_set3.getEntry(23);
409             fail("ArrayIndexOutOfBoundsException expected");
410         } catch (ArrayIndexOutOfBoundsException ex) {
411             // expected behavior
412         }
413 
414         ArrayFieldVector<Fraction> v_set4 = (ArrayFieldVector<Fraction>) v4.copy();
415         v_set4.setSubVector(3, v2_t);
416         assertEquals(new Fraction(4), v_set4.getEntry(3));
417         assertEquals(new Fraction(7), v_set4.getEntry(6));
418         try {
419             v_set4.setSubVector(7, v2_t);
420             fail("MathIllegalArgumentException expected");
421         } catch (MathIllegalArgumentException ex) {
422             // expected behavior
423         }
424 
425 
426         ArrayFieldVector<Fraction> vout10 = (ArrayFieldVector<Fraction>) v1.copy();
427         ArrayFieldVector<Fraction> vout10_2 = (ArrayFieldVector<Fraction>) v1.copy();
428         assertEquals(vout10, vout10_2);
429         vout10_2.setEntry(0, new Fraction(11, 10));
430         assertNotSame(vout10, vout10_2);
431 
432     }
433 
434     @Test
435     void testMapFunctions() {
436         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(vec1);
437 
438         //octave =  v1 .+ 2.0
439         FieldVector<Fraction> v_mapAdd = v1.mapAdd(new Fraction(2));
440         Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)};
441         checkArray("compare vectors" ,result_mapAdd,v_mapAdd.toArray());
442 
443         //octave =  v1 .+ 2.0
444         FieldVector<Fraction> v_mapAddToSelf = v1.copy();
445         v_mapAddToSelf.mapAddToSelf(new Fraction(2));
446         Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)};
447         checkArray("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.toArray());
448 
449         //octave =  v1 .- 2.0
450         FieldVector<Fraction> v_mapSubtract = v1.mapSubtract(new Fraction(2));
451         Fraction[] result_mapSubtract = {new Fraction(-1), Fraction.ZERO, new Fraction(1)};
452         checkArray("compare vectors" ,result_mapSubtract,v_mapSubtract.toArray());
453 
454         //octave =  v1 .- 2.0
455         FieldVector<Fraction> v_mapSubtractToSelf = v1.copy();
456         v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2));
457         Fraction[] result_mapSubtractToSelf = {new Fraction(-1), Fraction.ZERO, new Fraction(1)};
458         checkArray("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.toArray());
459 
460         //octave =  v1 .* 2.0
461         FieldVector<Fraction> v_mapMultiply = v1.mapMultiply(new Fraction(2));
462         Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)};
463         checkArray("compare vectors" ,result_mapMultiply,v_mapMultiply.toArray());
464 
465         //octave =  v1 .* 2.0
466         FieldVector<Fraction> v_mapMultiplyToSelf = v1.copy();
467         v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2));
468         Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)};
469         checkArray("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.toArray());
470 
471         //octave =  v1 ./ 2.0
472         FieldVector<Fraction> v_mapDivide = v1.mapDivide(new Fraction(2));
473         Fraction[] result_mapDivide = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)};
474         checkArray("compare vectors" ,result_mapDivide,v_mapDivide.toArray());
475 
476         //octave =  v1 ./ 2.0
477         FieldVector<Fraction> v_mapDivideToSelf = v1.copy();
478         v_mapDivideToSelf.mapDivideToSelf(new Fraction(2));
479         Fraction[] result_mapDivideToSelf = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)};
480         checkArray("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.toArray());
481 
482         //octave =  v1 .^-1
483         FieldVector<Fraction> v_mapInv = v1.mapInv();
484         Fraction[] result_mapInv = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)};
485         checkArray("compare vectors" ,result_mapInv,v_mapInv.toArray());
486 
487         //octave =  v1 .^-1
488         FieldVector<Fraction> v_mapInvToSelf = v1.copy();
489         v_mapInvToSelf.mapInvToSelf();
490         Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)};
491         checkArray("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.toArray());
492 
493     }
494 
495     @Test
496     void testBasicFunctions() {
497         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(vec1);
498         ArrayFieldVector<Fraction> v2 = new ArrayFieldVector<Fraction>(vec2);
499         new ArrayFieldVector<Fraction>(vec_null);
500 
501         FieldVectorTestImpl<Fraction> v2_t = new FieldVectorTestImpl<Fraction>(vec2);
502 
503         //octave =  v1 + v2
504         ArrayFieldVector<Fraction> v_add = v1.add(v2);
505         Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)};
506         checkArray("compare vect" ,v_add.toArray(),result_add);
507 
508         FieldVectorTestImpl<Fraction> vt2 = new FieldVectorTestImpl<Fraction>(vec2);
509         FieldVector<Fraction> v_add_i = v1.add(vt2);
510         Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)};
511         checkArray("compare vect" ,v_add_i.toArray(),result_add_i);
512 
513         //octave =  v1 - v2
514         ArrayFieldVector<Fraction> v_subtract = v1.subtract(v2);
515         Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
516         checkArray("compare vect" ,v_subtract.toArray(),result_subtract);
517 
518         FieldVector<Fraction> v_subtract_i = v1.subtract(vt2);
519         Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
520         checkArray("compare vect" ,v_subtract_i.toArray(),result_subtract_i);
521 
522         // octave v1 .* v2
523         ArrayFieldVector<Fraction>  v_ebeMultiply = v1.ebeMultiply(v2);
524         Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)};
525         checkArray("compare vect" ,v_ebeMultiply.toArray(),result_ebeMultiply);
526 
527         FieldVector<Fraction>  v_ebeMultiply_2 = v1.ebeMultiply(v2_t);
528         Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)};
529         checkArray("compare vect" ,v_ebeMultiply_2.toArray(),result_ebeMultiply_2);
530 
531         // octave v1 ./ v2
532         ArrayFieldVector<Fraction>  v_ebeDivide = v1.ebeDivide(v2);
533         Fraction[] result_ebeDivide = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)};
534         checkArray("compare vect" ,v_ebeDivide.toArray(),result_ebeDivide);
535 
536         FieldVector<Fraction>  v_ebeDivide_2 = v1.ebeDivide(v2_t);
537         Fraction[] result_ebeDivide_2 = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)};
538         checkArray("compare vect" ,v_ebeDivide_2.toArray(),result_ebeDivide_2);
539 
540         // octave  dot(v1,v2)
541         Fraction dot =  v1.dotProduct(v2);
542         assertEquals(new Fraction(32), dot, "compare val ");
543 
544         // octave  dot(v1,v2_t)
545         Fraction dot_2 =  v1.dotProduct(v2_t);
546         assertEquals(new Fraction(32), dot_2, "compare val ");
547 
548         FieldMatrix<Fraction> m_outerProduct = v1.outerProduct(v2);
549         assertEquals(new Fraction(4), m_outerProduct.getEntry(0,0), "compare val ");
550 
551         FieldMatrix<Fraction> m_outerProduct_2 = v1.outerProduct(v2_t);
552         assertEquals(new Fraction(4), m_outerProduct_2.getEntry(0,0), "compare val ");
553 
554         ArrayFieldVector<Fraction> v_projection = v1.projection(v2);
555         Fraction[] result_projection = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)};
556         checkArray("compare vect", v_projection.toArray(), result_projection);
557 
558         FieldVector<Fraction> v_projection_2 = v1.projection(v2_t);
559         Fraction[] result_projection_2 = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)};
560         checkArray("compare vect", v_projection_2.toArray(), result_projection_2);
561 
562      }
563 
564     @Test
565     void testMisc() {
566         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(vec1);
567         ArrayFieldVector<Fraction> v4 = new ArrayFieldVector<Fraction>(vec4);
568         FieldVector<Fraction> v4_2 = new ArrayFieldVector<Fraction>(vec4);
569 
570         assertEquals("{1; 2; 3}",  v1.toString());
571         assertEquals("{1; 2; 3; 4; 5; 6; 7; 8; 9}",  v4.toString());
572 
573         /*
574          Fraction[] dout1 = v1.copyOut();
575         Assertions.assertEquals(3, dout1.length);
576         assertNotSame("testData not same object ", v1.getDataRef(), dout1);
577          */
578         try {
579             v1.checkVectorDimensions(2);
580             fail("MathIllegalArgumentException expected");
581         } catch (MathIllegalArgumentException ex) {
582             // expected behavior
583         }
584 
585        try {
586             v1.checkVectorDimensions(v4);
587             fail("MathIllegalArgumentException expected");
588         } catch (MathIllegalArgumentException ex) {
589             // expected behavior
590         }
591 
592         try {
593             v1.checkVectorDimensions(v4_2);
594             fail("MathIllegalArgumentException expected");
595         } catch (MathIllegalArgumentException ex) {
596             // expected behavior
597         }
598 
599     }
600 
601     @Test
602     void testSerial()  {
603         ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(vec1);
604         assertEquals(v,UnitTestUtils.serializeAndRecover(v));
605     }
606 
607     @Test
608     void testZeroVectors() {
609 
610         // when the field is not specified, array cannot be empty
611         try {
612             new ArrayFieldVector<Fraction>(new Fraction[0]);
613             fail("MathIllegalArgumentException expected");
614         } catch (MathIllegalArgumentException ex) {
615             // expected behavior
616         }
617         try {
618             new ArrayFieldVector<Fraction>(new Fraction[0], true);
619             fail("MathIllegalArgumentException expected");
620         } catch (MathIllegalArgumentException ex) {
621             // expected behavior
622         }
623         try {
624             new ArrayFieldVector<Fraction>(new Fraction[0], false);
625             fail("MathIllegalArgumentException expected");
626         } catch (MathIllegalArgumentException ex) {
627             // expected behavior
628         }
629 
630         // when the field is specified, array can be empty
631         assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0]).getDimension());
632         assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0], true).getDimension());
633         assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0], false).getDimension());
634 
635     }
636 
637     @Test
638     void testOuterProduct() {
639         final ArrayFieldVector<Fraction> u
640             = new ArrayFieldVector<Fraction>(FractionField.getInstance(),
641                                              new Fraction[] {new Fraction(1),
642                                                              new Fraction(2),
643                                                              new Fraction(-3)});
644         final ArrayFieldVector<Fraction> v
645             = new ArrayFieldVector<Fraction>(FractionField.getInstance(),
646                                              new Fraction[] {new Fraction(4),
647                                                              new Fraction(-2)});
648 
649         final FieldMatrix<Fraction> uv = u.outerProduct(v);
650 
651         final double tol = Math.ulp(1d);
652         assertEquals(new Fraction(4).doubleValue(), uv.getEntry(0, 0).doubleValue(), tol);
653         assertEquals(new Fraction(-2).doubleValue(), uv.getEntry(0, 1).doubleValue(), tol);
654         assertEquals(new Fraction(8).doubleValue(), uv.getEntry(1, 0).doubleValue(), tol);
655         assertEquals(new Fraction(-4).doubleValue(), uv.getEntry(1, 1).doubleValue(), tol);
656         assertEquals(new Fraction(-12).doubleValue(), uv.getEntry(2, 0).doubleValue(), tol);
657         assertEquals(new Fraction(6).doubleValue(), uv.getEntry(2, 1).doubleValue(), tol);
658     }
659 
660     /** verifies that two vectors are equals */
661     protected void checkArray(String msg, Fraction[] m, Fraction[] n) {
662         if (m.length != n.length) {
663             fail("vectors have different lengths");
664         }
665         for (int i = 0; i < m.length; i++) {
666             assertEquals(m[i],n[i],msg + " " +  i + " elements differ");
667         }
668     }
669 
670     /*
671      * TESTS OF THE VISITOR PATTERN
672      */
673 
674     /** The whole vector is visited. */
675     @Test
676     void testWalkInDefaultOrderPreservingVisitor1() {
677         final Fraction[] data = new Fraction[] {
678             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
679             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
680             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
681         };
682         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
683         final FieldVectorPreservingVisitor<Fraction> visitor;
684         visitor = new FieldVectorPreservingVisitor<Fraction>() {
685 
686             private int expectedIndex;
687 
688             public void visit(final int actualIndex, final Fraction actualValue) {
689                 assertEquals(expectedIndex, actualIndex);
690                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
691                 ++expectedIndex;
692             }
693 
694             public void start(final int actualSize, final int actualStart,
695                               final int actualEnd) {
696                 assertEquals(data.length, actualSize);
697                 assertEquals(0, actualStart);
698                 assertEquals(data.length - 1, actualEnd);
699                 expectedIndex = 0;
700             }
701 
702             public Fraction end() {
703                 return Fraction.ZERO;
704             }
705         };
706         v.walkInDefaultOrder(visitor);
707     }
708 
709     /** Visiting an invalid subvector. */
710     @Test
711     void testWalkInDefaultOrderPreservingVisitor2() {
712         final ArrayFieldVector<Fraction> v = create(5);
713         final FieldVectorPreservingVisitor<Fraction> visitor;
714         visitor = new FieldVectorPreservingVisitor<Fraction>() {
715 
716             public void visit(int index, Fraction value) {
717                 // Do nothing
718             }
719 
720             public void start(int dimension, int start, int end) {
721                 // Do nothing
722             }
723 
724             public Fraction end() {
725                 return Fraction.ZERO;
726             }
727         };
728         try {
729             v.walkInDefaultOrder(visitor, -1, 4);
730             fail();
731         } catch (MathIllegalArgumentException e) {
732             // Expected behavior
733         }
734         try {
735             v.walkInDefaultOrder(visitor, 5, 4);
736             fail();
737         } catch (MathIllegalArgumentException e) {
738             // Expected behavior
739         }
740         try {
741             v.walkInDefaultOrder(visitor, 0, -1);
742             fail();
743         } catch (MathIllegalArgumentException e) {
744             // Expected behavior
745         }
746         try {
747             v.walkInDefaultOrder(visitor, 0, 5);
748             fail();
749         } catch (MathIllegalArgumentException e) {
750             // Expected behavior
751         }
752         try {
753             v.walkInDefaultOrder(visitor, 4, 0);
754             fail();
755         } catch (MathIllegalArgumentException e) {
756             // Expected behavior
757         }
758     }
759 
760     /** Visiting a valid subvector. */
761     @Test
762     void testWalkInDefaultOrderPreservingVisitor3() {
763         final Fraction[] data = new Fraction[] {
764             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
765             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
766             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
767         };
768         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
769         final int expectedStart = 2;
770         final int expectedEnd = 7;
771         final FieldVectorPreservingVisitor<Fraction> visitor;
772         visitor = new FieldVectorPreservingVisitor<Fraction>() {
773 
774             private int expectedIndex;
775 
776             public void visit(final int actualIndex, final Fraction actualValue) {
777                 assertEquals(expectedIndex, actualIndex);
778                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
779                 ++expectedIndex;
780             }
781 
782             public void start(final int actualSize, final int actualStart,
783                               final int actualEnd) {
784                 assertEquals(data.length, actualSize);
785                 assertEquals(expectedStart, actualStart);
786                 assertEquals(expectedEnd, actualEnd);
787                 expectedIndex = expectedStart;
788             }
789 
790             public Fraction end() {
791                 return Fraction.ZERO;
792             }
793         };
794         v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
795     }
796 
797     /** The whole vector is visited. */
798     @Test
799     void testWalkInOptimizedOrderPreservingVisitor1() {
800         final Fraction[] data = new Fraction[] {
801             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
802             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
803             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
804         };
805         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
806         final FieldVectorPreservingVisitor<Fraction> visitor;
807         visitor = new FieldVectorPreservingVisitor<Fraction>() {
808             private final boolean[] visited = new boolean[data.length];
809 
810             public void visit(final int actualIndex, final Fraction actualValue) {
811                 visited[actualIndex] = true;
812                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
813             }
814 
815             public void start(final int actualSize, final int actualStart,
816                               final int actualEnd) {
817                 assertEquals(data.length, actualSize);
818                 assertEquals(0, actualStart);
819                 assertEquals(data.length - 1, actualEnd);
820                 Arrays.fill(visited, false);
821             }
822 
823             public Fraction end() {
824                 for (int i = 0; i < data.length; i++) {
825                     assertTrue(visited[i],
826                                       "entry " + i + "has not been visited");
827                 }
828                 return Fraction.ZERO;
829             }
830         };
831         v.walkInOptimizedOrder(visitor);
832     }
833 
834     /** Visiting an invalid subvector. */
835     @Test
836     void testWalkInOptimizedOrderPreservingVisitor2() {
837         final ArrayFieldVector<Fraction> v = create(5);
838         final FieldVectorPreservingVisitor<Fraction> visitor;
839         visitor = new FieldVectorPreservingVisitor<Fraction>() {
840 
841             public void visit(int index, Fraction value) {
842                 // Do nothing
843             }
844 
845             public void start(int dimension, int start, int end) {
846                 // Do nothing
847             }
848 
849             public Fraction end() {
850                 return Fraction.ZERO;
851             }
852         };
853         try {
854             v.walkInOptimizedOrder(visitor, -1, 4);
855             fail();
856         } catch (MathIllegalArgumentException e) {
857             // Expected behavior
858         }
859         try {
860             v.walkInOptimizedOrder(visitor, 5, 4);
861             fail();
862         } catch (MathIllegalArgumentException e) {
863             // Expected behavior
864         }
865         try {
866             v.walkInOptimizedOrder(visitor, 0, -1);
867             fail();
868         } catch (MathIllegalArgumentException e) {
869             // Expected behavior
870         }
871         try {
872             v.walkInOptimizedOrder(visitor, 0, 5);
873             fail();
874         } catch (MathIllegalArgumentException e) {
875             // Expected behavior
876         }
877         try {
878             v.walkInOptimizedOrder(visitor, 4, 0);
879             fail();
880         } catch (MathIllegalArgumentException e) {
881             // Expected behavior
882         }
883     }
884 
885     /** Visiting a valid subvector. */
886     @Test
887     void testWalkInOptimizedOrderPreservingVisitor3() {
888         final Fraction[] data = new Fraction[] {
889             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
890             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
891             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
892         };
893         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
894         final int expectedStart = 2;
895         final int expectedEnd = 7;
896         final FieldVectorPreservingVisitor<Fraction> visitor;
897         visitor = new FieldVectorPreservingVisitor<Fraction>() {
898             private final boolean[] visited = new boolean[data.length];
899 
900             public void visit(final int actualIndex, final Fraction actualValue) {
901                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
902                 visited[actualIndex] = true;
903             }
904 
905             public void start(final int actualSize, final int actualStart,
906                               final int actualEnd) {
907                 assertEquals(data.length, actualSize);
908                 assertEquals(expectedStart, actualStart);
909                 assertEquals(expectedEnd, actualEnd);
910                 Arrays.fill(visited, true);
911             }
912 
913             public Fraction end() {
914                 for (int i = expectedStart; i <= expectedEnd; i++) {
915                     assertTrue(visited[i],
916                                       "entry " + i + "has not been visited");
917                 }
918                 return Fraction.ZERO;
919             }
920         };
921         v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
922     }
923 
924     /** The whole vector is visited. */
925     @Test
926     void testWalkInDefaultOrderChangingVisitor1() {
927         final Fraction[] data = new Fraction[] {
928             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
929             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
930             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
931         };
932         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
933         final FieldVectorChangingVisitor<Fraction> visitor;
934         visitor = new FieldVectorChangingVisitor<Fraction>() {
935 
936             private int expectedIndex;
937 
938             public Fraction visit(final int actualIndex, final Fraction actualValue) {
939                 assertEquals(expectedIndex, actualIndex);
940                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
941                 ++expectedIndex;
942                 return actualValue.add(actualIndex);
943             }
944 
945             public void start(final int actualSize, final int actualStart,
946                               final int actualEnd) {
947                 assertEquals(data.length, actualSize);
948                 assertEquals(0, actualStart);
949                 assertEquals(data.length - 1, actualEnd);
950                 expectedIndex = 0;
951             }
952 
953             public Fraction end() {
954                 return Fraction.ZERO;
955             }
956         };
957         v.walkInDefaultOrder(visitor);
958         for (int i = 0; i < data.length; i++) {
959             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
960         }
961     }
962 
963     /** Visiting an invalid subvector. */
964     @Test
965     void testWalkInDefaultOrderChangingVisitor2() {
966         final ArrayFieldVector<Fraction> v = create(5);
967         final FieldVectorChangingVisitor<Fraction> visitor;
968         visitor = new FieldVectorChangingVisitor<Fraction>() {
969 
970             public Fraction visit(int index, Fraction value) {
971                 return Fraction.ZERO;
972             }
973 
974             public void start(int dimension, int start, int end) {
975                 // Do nothing
976             }
977 
978             public Fraction end() {
979                 return Fraction.ZERO;
980             }
981         };
982         try {
983             v.walkInDefaultOrder(visitor, -1, 4);
984             fail();
985         } catch (MathIllegalArgumentException e) {
986             // Expected behavior
987         }
988         try {
989             v.walkInDefaultOrder(visitor, 5, 4);
990             fail();
991         } catch (MathIllegalArgumentException e) {
992             // Expected behavior
993         }
994         try {
995             v.walkInDefaultOrder(visitor, 0, -1);
996             fail();
997         } catch (MathIllegalArgumentException e) {
998             // Expected behavior
999         }
1000         try {
1001             v.walkInDefaultOrder(visitor, 0, 5);
1002             fail();
1003         } catch (MathIllegalArgumentException e) {
1004             // Expected behavior
1005         }
1006         try {
1007             v.walkInDefaultOrder(visitor, 4, 0);
1008             fail();
1009         } catch (MathIllegalArgumentException e) {
1010             // Expected behavior
1011         }
1012     }
1013 
1014     /** Visiting a valid subvector. */
1015     @Test
1016     void testWalkInDefaultOrderChangingVisitor3() {
1017         final Fraction[] data = new Fraction[] {
1018             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
1019             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
1020             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
1021         };
1022         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
1023         final int expectedStart = 2;
1024         final int expectedEnd = 7;
1025         final FieldVectorChangingVisitor<Fraction> visitor;
1026         visitor = new FieldVectorChangingVisitor<Fraction>() {
1027 
1028             private int expectedIndex;
1029 
1030             public Fraction visit(final int actualIndex, final Fraction actualValue) {
1031                 assertEquals(expectedIndex, actualIndex);
1032                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
1033                 ++expectedIndex;
1034                 return actualValue.add(actualIndex);
1035             }
1036 
1037             public void start(final int actualSize, final int actualStart,
1038                               final int actualEnd) {
1039                 assertEquals(data.length, actualSize);
1040                 assertEquals(expectedStart, actualStart);
1041                 assertEquals(expectedEnd, actualEnd);
1042                 expectedIndex = expectedStart;
1043             }
1044 
1045             public Fraction end() {
1046                 return Fraction.ZERO;
1047             }
1048         };
1049         v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
1050         for (int i = expectedStart; i <= expectedEnd; i++) {
1051             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
1052         }
1053     }
1054 
1055     /** The whole vector is visited. */
1056     @Test
1057     void testWalkInOptimizedOrderChangingVisitor1() {
1058         final Fraction[] data = new Fraction[] {
1059             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
1060             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
1061             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
1062         };
1063         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
1064         final FieldVectorChangingVisitor<Fraction> visitor;
1065         visitor = new FieldVectorChangingVisitor<Fraction>() {
1066             private final boolean[] visited = new boolean[data.length];
1067 
1068             public Fraction visit(final int actualIndex, final Fraction actualValue) {
1069                 visited[actualIndex] = true;
1070                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
1071                 return actualValue.add(actualIndex);
1072             }
1073 
1074             public void start(final int actualSize, final int actualStart,
1075                               final int actualEnd) {
1076                 assertEquals(data.length, actualSize);
1077                 assertEquals(0, actualStart);
1078                 assertEquals(data.length - 1, actualEnd);
1079                 Arrays.fill(visited, false);
1080             }
1081 
1082             public Fraction end() {
1083                 for (int i = 0; i < data.length; i++) {
1084                     assertTrue(visited[i],
1085                                       "entry " + i + "has not been visited");
1086                 }
1087                 return Fraction.ZERO;
1088             }
1089         };
1090         v.walkInOptimizedOrder(visitor);
1091         for (int i = 0; i < data.length; i++) {
1092             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
1093         }
1094     }
1095 
1096     /** Visiting an invalid subvector. */
1097     @Test
1098     void testWalkInOptimizedOrderChangingVisitor2() {
1099         final ArrayFieldVector<Fraction> v = create(5);
1100         final FieldVectorChangingVisitor<Fraction> visitor;
1101         visitor = new FieldVectorChangingVisitor<Fraction>() {
1102 
1103             public Fraction visit(int index, Fraction value) {
1104                 return Fraction.ZERO;
1105             }
1106 
1107             public void start(int dimension, int start, int end) {
1108                 // Do nothing
1109             }
1110 
1111             public Fraction end() {
1112                 return Fraction.ZERO;
1113             }
1114         };
1115         try {
1116             v.walkInOptimizedOrder(visitor, -1, 4);
1117             fail();
1118         } catch (MathIllegalArgumentException e) {
1119             // Expected behavior
1120         }
1121         try {
1122             v.walkInOptimizedOrder(visitor, 5, 4);
1123             fail();
1124         } catch (MathIllegalArgumentException e) {
1125             // Expected behavior
1126         }
1127         try {
1128             v.walkInOptimizedOrder(visitor, 0, -1);
1129             fail();
1130         } catch (MathIllegalArgumentException e) {
1131             // Expected behavior
1132         }
1133         try {
1134             v.walkInOptimizedOrder(visitor, 0, 5);
1135             fail();
1136         } catch (MathIllegalArgumentException e) {
1137             // Expected behavior
1138         }
1139         try {
1140             v.walkInOptimizedOrder(visitor, 4, 0);
1141             fail();
1142         } catch (MathIllegalArgumentException e) {
1143             // Expected behavior
1144         }
1145     }
1146 
1147     /** Visiting a valid subvector. */
1148     @Test
1149     void testWalkInOptimizedOrderChangingVisitor3() {
1150         final Fraction[] data = new Fraction[] {
1151             Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
1152             Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
1153             Fraction.ZERO, Fraction.ZERO, new Fraction(3)
1154         };
1155         final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
1156         final int expectedStart = 2;
1157         final int expectedEnd = 7;
1158         final FieldVectorChangingVisitor<Fraction> visitor;
1159         visitor = new FieldVectorChangingVisitor<Fraction>() {
1160             private final boolean[] visited = new boolean[data.length];
1161 
1162             public Fraction visit(final int actualIndex, final Fraction actualValue) {
1163                 assertEquals(data[actualIndex], actualValue, Integer.toString(actualIndex));
1164                 visited[actualIndex] = true;
1165                 return actualValue.add(actualIndex);
1166             }
1167 
1168             public void start(final int actualSize, final int actualStart,
1169                               final int actualEnd) {
1170                 assertEquals(data.length, actualSize);
1171                 assertEquals(expectedStart, actualStart);
1172                 assertEquals(expectedEnd, actualEnd);
1173                 Arrays.fill(visited, true);
1174             }
1175 
1176             public Fraction end() {
1177                 for (int i = expectedStart; i <= expectedEnd; i++) {
1178                     assertTrue(visited[i],
1179                                       "entry " + i + "has not been visited");
1180                 }
1181                 return Fraction.ZERO;
1182             }
1183         };
1184         v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
1185         for (int i = expectedStart; i <= expectedEnd; i++) {
1186             assertEquals(data[i].add(i), v.getEntry(i), "entry " + i);
1187         }
1188     }
1189 
1190     private ArrayFieldVector<Fraction> create(int n) {
1191         Fraction[] t = new Fraction[n];
1192         for (int i = 0; i < n; ++i) {
1193             t[i] = Fraction.ZERO;
1194         }
1195         return new ArrayFieldVector<Fraction>(t);
1196     }
1197 }