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  
18  package org.apache.commons.math3.linear;
19  
20  import java.util.Iterator;
21  import java.util.NoSuchElementException;
22  
23  import org.apache.commons.math3.exception.MathUnsupportedOperationException;
24  import org.apache.commons.math3.exception.DimensionMismatchException;
25  import org.apache.commons.math3.exception.NotPositiveException;
26  import org.apache.commons.math3.exception.NumberIsTooSmallException;
27  import org.apache.commons.math3.exception.OutOfRangeException;
28  import org.apache.commons.math3.exception.MathArithmeticException;
29  import org.apache.commons.math3.analysis.FunctionUtils;
30  import org.apache.commons.math3.analysis.function.Add;
31  import org.apache.commons.math3.analysis.function.Multiply;
32  import org.apache.commons.math3.analysis.function.Divide;
33  import org.apache.commons.math3.analysis.UnivariateFunction;
34  import org.apache.commons.math3.exception.util.LocalizedFormats;
35  import org.apache.commons.math3.util.FastMath;
36  
37  /**
38   * Class defining a real-valued vector with basic algebraic operations.
39   * <p>
40   * vector element indexing is 0-based -- e.g., {@code getEntry(0)}
41   * returns the first element of the vector.
42   * </p>
43   * <p>
44   * The {@code code map} and {@code mapToSelf} methods operate
45   * on vectors element-wise, i.e. they perform the same operation (adding a scalar,
46   * applying a function ...) on each element in turn. The {@code map}
47   * versions create a new vector to hold the result and do not change the instance.
48   * The {@code mapToSelf} version uses the instance itself to store the
49   * results, so the instance is changed by this method. In all cases, the result
50   * vector is returned by the methods, allowing the <i>fluent API</i>
51   * style, like this:
52   * </p>
53   * <pre>
54   *   RealVector result = v.mapAddToSelf(3.4).mapToSelf(new Tan()).mapToSelf(new Power(2.3));
55   * </pre>
56   *
57   * @since 2.1
58   */
59  public abstract class RealVector {
60      /**
61       * Returns the size of the vector.
62       *
63       * @return the size of this vector.
64       */
65      public abstract int getDimension();
66  
67      /**
68       * Return the entry at the specified index.
69       *
70       * @param index Index location of entry to be fetched.
71       * @return the vector entry at {@code index}.
72       * @throws OutOfRangeException if the index is not valid.
73       * @see #setEntry(int, double)
74       */
75      public abstract double getEntry(int index) throws OutOfRangeException;
76  
77      /**
78       * Set a single element.
79       *
80       * @param index element index.
81       * @param value new value for the element.
82       * @throws OutOfRangeException if the index is not valid.
83       * @see #getEntry(int)
84       */
85      public abstract void setEntry(int index, double value)
86          throws OutOfRangeException;
87  
88      /**
89       * Change an entry at the specified index.
90       *
91       * @param index Index location of entry to be set.
92       * @param increment Value to add to the vector entry.
93       * @throws OutOfRangeException if the index is not valid.
94       * @since 3.0
95       */
96      public void addToEntry(int index, double increment)
97          throws OutOfRangeException {
98          setEntry(index, getEntry(index) + increment);
99      }
100 
101     /**
102      * Construct a new vector by appending a vector to this vector.
103      *
104      * @param v vector to append to this one.
105      * @return a new vector.
106      */
107     public abstract RealVector append(RealVector v);
108 
109     /**
110      * Construct a new vector by appending a double to this vector.
111      *
112      * @param d double to append.
113      * @return a new vector.
114      */
115     public abstract RealVector append(double d);
116 
117     /**
118      * Get a subvector from consecutive elements.
119      *
120      * @param index index of first element.
121      * @param n number of elements to be retrieved.
122      * @return a vector containing n elements.
123      * @throws OutOfRangeException if the index is not valid.
124      * @throws NotPositiveException if the number of elements is not positive.
125      */
126     public abstract RealVector getSubVector(int index, int n)
127         throws NotPositiveException, OutOfRangeException;
128 
129     /**
130      * Set a sequence of consecutive elements.
131      *
132      * @param index index of first element to be set.
133      * @param v vector containing the values to set.
134      * @throws OutOfRangeException if the index is not valid.
135      */
136     public abstract void setSubVector(int index, RealVector v)
137         throws OutOfRangeException;
138 
139     /**
140      * Check whether any coordinate of this vector is {@code NaN}.
141      *
142      * @return {@code true} if any coordinate of this vector is {@code NaN},
143      * {@code false} otherwise.
144      */
145     public abstract boolean isNaN();
146 
147     /**
148      * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
149      *
150      * @return {@code true} if any coordinate of this vector is infinite and
151      * none are {@code NaN}, {@code false} otherwise.
152      */
153     public abstract boolean isInfinite();
154 
155     /**
156      * Check if instance and specified vectors have the same dimension.
157      *
158      * @param v Vector to compare instance with.
159      * @throws DimensionMismatchException if the vectors do not
160      * have the same dimension.
161      */
162     protected void checkVectorDimensions(RealVector v)
163         throws DimensionMismatchException {
164         checkVectorDimensions(v.getDimension());
165     }
166 
167     /**
168      * Check if instance dimension is equal to some expected value.
169      *
170      * @param n Expected dimension.
171      * @throws DimensionMismatchException if the dimension is
172      * inconsistent with the vector size.
173      */
174     protected void checkVectorDimensions(int n)
175         throws DimensionMismatchException {
176         int d = getDimension();
177         if (d != n) {
178             throw new DimensionMismatchException(d, n);
179         }
180     }
181 
182     /**
183      * Check if an index is valid.
184      *
185      * @param index Index to check.
186      * @exception OutOfRangeException if {@code index} is not valid.
187      */
188     protected void checkIndex(final int index) throws OutOfRangeException {
189         if (index < 0 ||
190             index >= getDimension()) {
191             throw new OutOfRangeException(LocalizedFormats.INDEX,
192                                           index, 0, getDimension() - 1);
193         }
194     }
195 
196     /**
197      * Checks that the indices of a subvector are valid.
198      *
199      * @param start the index of the first entry of the subvector
200      * @param end the index of the last entry of the subvector (inclusive)
201      * @throws OutOfRangeException if {@code start} of {@code end} are not valid
202      * @throws NumberIsTooSmallException if {@code end < start}
203      * @since 3.1
204      */
205     protected void checkIndices(final int start, final int end)
206         throws NumberIsTooSmallException, OutOfRangeException {
207         final int dim = getDimension();
208         if ((start < 0) || (start >= dim)) {
209             throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
210                                           dim - 1);
211         }
212         if ((end < 0) || (end >= dim)) {
213             throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
214                                           dim - 1);
215         }
216         if (end < start) {
217             // TODO Use more specific error message
218             throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
219                                                 end, start, false);
220         }
221     }
222 
223     /**
224      * Compute the sum of this vector and {@code v}.
225      * Returns a new vector. Does not change instance data.
226      *
227      * @param v Vector to be added.
228      * @return {@code this} + {@code v}.
229      * @throws DimensionMismatchException if {@code v} is not the same size as
230      * {@code this} vector.
231      */
232     public RealVector add(RealVector v) throws DimensionMismatchException {
233         checkVectorDimensions(v);
234         RealVector result = v.copy();
235         Iterator<Entry> it = iterator();
236         while (it.hasNext()) {
237             final Entry e = it.next();
238             final int index = e.getIndex();
239             result.setEntry(index, e.getValue() + result.getEntry(index));
240         }
241         return result;
242     }
243 
244     /**
245      * Subtract {@code v} from this vector.
246      * Returns a new vector. Does not change instance data.
247      *
248      * @param v Vector to be subtracted.
249      * @return {@code this} - {@code v}.
250      * @throws DimensionMismatchException if {@code v} is not the same size as
251      * {@code this} vector.
252      */
253     public RealVector subtract(RealVector v) throws DimensionMismatchException {
254         checkVectorDimensions(v);
255         RealVector result = v.mapMultiply(-1d);
256         Iterator<Entry> it = iterator();
257         while (it.hasNext()) {
258             final Entry e = it.next();
259             final int index = e.getIndex();
260             result.setEntry(index, e.getValue() + result.getEntry(index));
261         }
262         return result;
263     }
264 
265     /**
266      * Add a value to each entry.
267      * Returns a new vector. Does not change instance data.
268      *
269      * @param d Value to be added to each entry.
270      * @return {@code this} + {@code d}.
271      */
272     public RealVector mapAdd(double d) {
273         return copy().mapAddToSelf(d);
274     }
275 
276     /**
277      * Add a value to each entry.
278      * The instance is changed in-place.
279      *
280      * @param d Value to be added to each entry.
281      * @return {@code this}.
282      */
283     public RealVector mapAddToSelf(double d) {
284         if (d != 0) {
285             return mapToSelf(FunctionUtils.fix2ndArgument(new Add(), d));
286         }
287         return this;
288     }
289 
290     /**
291      * Returns a (deep) copy of this vector.
292      *
293      * @return a vector copy.
294      */
295     public abstract RealVector copy();
296 
297     /**
298      * Compute the dot product of this vector with {@code v}.
299      *
300      * @param v Vector with which dot product should be computed
301      * @return the scalar dot product between this instance and {@code v}.
302      * @throws DimensionMismatchException if {@code v} is not the same size as
303      * {@code this} vector.
304      */
305     public double dotProduct(RealVector v) throws DimensionMismatchException {
306         checkVectorDimensions(v);
307         double d = 0;
308         final int n = getDimension();
309         for (int i = 0; i < n; i++) {
310             d += getEntry(i) * v.getEntry(i);
311         }
312         return d;
313     }
314 
315     /**
316      * Computes the cosine of the angle between this vector and the
317      * argument.
318      *
319      * @param v Vector.
320      * @return the cosine of the angle between this vector and {@code v}.
321      * @throws MathArithmeticException if {@code this} or {@code v} is the null
322      * vector
323      * @throws DimensionMismatchException if the dimensions of {@code this} and
324      * {@code v} do not match
325      */
326     public double cosine(RealVector v) throws DimensionMismatchException,
327         MathArithmeticException {
328         final double norm = getNorm();
329         final double vNorm = v.getNorm();
330 
331         if (norm == 0 ||
332             vNorm == 0) {
333             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
334         }
335         return dotProduct(v) / (norm * vNorm);
336     }
337 
338     /**
339      * Element-by-element division.
340      *
341      * @param v Vector by which instance elements must be divided.
342      * @return a vector containing this[i] / v[i] for all i.
343      * @throws DimensionMismatchException if {@code v} is not the same size as
344      * {@code this} vector.
345      */
346     public abstract RealVector ebeDivide(RealVector v)
347         throws DimensionMismatchException;
348 
349     /**
350      * Element-by-element multiplication.
351      *
352      * @param v Vector by which instance elements must be multiplied
353      * @return a vector containing this[i] * v[i] for all i.
354      * @throws DimensionMismatchException if {@code v} is not the same size as
355      * {@code this} vector.
356      */
357     public abstract RealVector ebeMultiply(RealVector v)
358         throws DimensionMismatchException;
359 
360     /**
361      * Distance between two vectors.
362      * <p>This method computes the distance consistent with the
363      * L<sub>2</sub> norm, i.e. the square root of the sum of
364      * element differences, or Euclidean distance.</p>
365      *
366      * @param v Vector to which distance is requested.
367      * @return the distance between two vectors.
368      * @throws DimensionMismatchException if {@code v} is not the same size as
369      * {@code this} vector.
370      * @see #getL1Distance(RealVector)
371      * @see #getLInfDistance(RealVector)
372      * @see #getNorm()
373      */
374     public double getDistance(RealVector v) throws DimensionMismatchException {
375         checkVectorDimensions(v);
376         double d = 0;
377         Iterator<Entry> it = iterator();
378         while (it.hasNext()) {
379             final Entry e = it.next();
380             final double diff = e.getValue() - v.getEntry(e.getIndex());
381             d += diff * diff;
382         }
383         return FastMath.sqrt(d);
384     }
385 
386     /**
387      * Returns the L<sub>2</sub> norm of the vector.
388      * <p>The L<sub>2</sub> norm is the root of the sum of
389      * the squared elements.</p>
390      *
391      * @return the norm.
392      * @see #getL1Norm()
393      * @see #getLInfNorm()
394      * @see #getDistance(RealVector)
395      */
396     public double getNorm() {
397         double sum = 0;
398         Iterator<Entry> it = iterator();
399         while (it.hasNext()) {
400             final Entry e = it.next();
401             final double value = e.getValue();
402             sum += value * value;
403         }
404         return FastMath.sqrt(sum);
405     }
406 
407     /**
408      * Returns the L<sub>1</sub> norm of the vector.
409      * <p>The L<sub>1</sub> norm is the sum of the absolute
410      * values of the elements.</p>
411      *
412      * @return the norm.
413      * @see #getNorm()
414      * @see #getLInfNorm()
415      * @see #getL1Distance(RealVector)
416      */
417     public double getL1Norm() {
418         double norm = 0;
419         Iterator<Entry> it = iterator();
420         while (it.hasNext()) {
421             final Entry e = it.next();
422             norm += FastMath.abs(e.getValue());
423         }
424         return norm;
425     }
426 
427     /**
428      * Returns the L<sub>&infin;</sub> norm of the vector.
429      * <p>The L<sub>&infin;</sub> norm is the max of the absolute
430      * values of the elements.</p>
431      *
432      * @return the norm.
433      * @see #getNorm()
434      * @see #getL1Norm()
435      * @see #getLInfDistance(RealVector)
436      */
437     public double getLInfNorm() {
438         double norm = 0;
439         Iterator<Entry> it = iterator();
440         while (it.hasNext()) {
441             final Entry e = it.next();
442             norm = FastMath.max(norm, FastMath.abs(e.getValue()));
443         }
444         return norm;
445     }
446 
447     /**
448      * Distance between two vectors.
449      * <p>This method computes the distance consistent with
450      * L<sub>1</sub> norm, i.e. the sum of the absolute values of
451      * the elements differences.</p>
452      *
453      * @param v Vector to which distance is requested.
454      * @return the distance between two vectors.
455      * @throws DimensionMismatchException if {@code v} is not the same size as
456      * {@code this} vector.
457      */
458     public double getL1Distance(RealVector v)
459         throws DimensionMismatchException {
460         checkVectorDimensions(v);
461         double d = 0;
462         Iterator<Entry> it = iterator();
463         while (it.hasNext()) {
464             final Entry e = it.next();
465             d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
466         }
467         return d;
468     }
469 
470     /**
471      * Distance between two vectors.
472      * <p>This method computes the distance consistent with
473      * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
474      * element differences.</p>
475      *
476      * @param v Vector to which distance is requested.
477      * @return the distance between two vectors.
478      * @throws DimensionMismatchException if {@code v} is not the same size as
479      * {@code this} vector.
480      * @see #getDistance(RealVector)
481      * @see #getL1Distance(RealVector)
482      * @see #getLInfNorm()
483      */
484     public double getLInfDistance(RealVector v)
485         throws DimensionMismatchException {
486         checkVectorDimensions(v);
487         double d = 0;
488         Iterator<Entry> it = iterator();
489         while (it.hasNext()) {
490             final Entry e = it.next();
491             d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
492         }
493         return d;
494     }
495 
496     /**
497      * Get the index of the minimum entry.
498      *
499      * @return the index of the minimum entry or -1 if vector length is 0
500      * or all entries are {@code NaN}.
501      */
502     public int getMinIndex() {
503         int minIndex    = -1;
504         double minValue = Double.POSITIVE_INFINITY;
505         Iterator<Entry> iterator = iterator();
506         while (iterator.hasNext()) {
507             final Entry entry = iterator.next();
508             if (entry.getValue() <= minValue) {
509                 minIndex = entry.getIndex();
510                 minValue = entry.getValue();
511             }
512         }
513         return minIndex;
514     }
515 
516     /**
517      * Get the value of the minimum entry.
518      *
519      * @return the value of the minimum entry or {@code NaN} if all
520      * entries are {@code NaN}.
521      */
522     public double getMinValue() {
523         final int minIndex = getMinIndex();
524         return minIndex < 0 ? Double.NaN : getEntry(minIndex);
525     }
526 
527     /**
528      * Get the index of the maximum entry.
529      *
530      * @return the index of the maximum entry or -1 if vector length is 0
531      * or all entries are {@code NaN}
532      */
533     public int getMaxIndex() {
534         int maxIndex    = -1;
535         double maxValue = Double.NEGATIVE_INFINITY;
536         Iterator<Entry> iterator = iterator();
537         while (iterator.hasNext()) {
538             final Entry entry = iterator.next();
539             if (entry.getValue() >= maxValue) {
540                 maxIndex = entry.getIndex();
541                 maxValue = entry.getValue();
542             }
543         }
544         return maxIndex;
545     }
546 
547     /**
548      * Get the value of the maximum entry.
549      *
550      * @return the value of the maximum entry or {@code NaN} if all
551      * entries are {@code NaN}.
552      */
553     public double getMaxValue() {
554         final int maxIndex = getMaxIndex();
555         return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
556     }
557 
558 
559     /**
560      * Multiply each entry by the argument. Returns a new vector.
561      * Does not change instance data.
562      *
563      * @param d Multiplication factor.
564      * @return {@code this} * {@code d}.
565      */
566     public RealVector mapMultiply(double d) {
567         return copy().mapMultiplyToSelf(d);
568     }
569 
570     /**
571      * Multiply each entry.
572      * The instance is changed in-place.
573      *
574      * @param d Multiplication factor.
575      * @return {@code this}.
576      */
577     public RealVector mapMultiplyToSelf(double d){
578         return mapToSelf(FunctionUtils.fix2ndArgument(new Multiply(), d));
579     }
580 
581     /**
582      * Subtract a value from each entry. Returns a new vector.
583      * Does not change instance data.
584      *
585      * @param d Value to be subtracted.
586      * @return {@code this} - {@code d}.
587      */
588     public RealVector mapSubtract(double d) {
589         return copy().mapSubtractToSelf(d);
590     }
591 
592     /**
593      * Subtract a value from each entry.
594      * The instance is changed in-place.
595      *
596      * @param d Value to be subtracted.
597      * @return {@code this}.
598      */
599     public RealVector mapSubtractToSelf(double d){
600         return mapAddToSelf(-d);
601     }
602 
603     /**
604      * Divide each entry by the argument. Returns a new vector.
605      * Does not change instance data.
606      *
607      * @param d Value to divide by.
608      * @return {@code this} / {@code d}.
609      */
610     public RealVector mapDivide(double d) {
611         return copy().mapDivideToSelf(d);
612     }
613 
614     /**
615      * Divide each entry by the argument.
616      * The instance is changed in-place.
617      *
618      * @param d Value to divide by.
619      * @return {@code this}.
620      */
621     public RealVector mapDivideToSelf(double d){
622         return mapToSelf(FunctionUtils.fix2ndArgument(new Divide(), d));
623     }
624 
625     /**
626      * Compute the outer product.
627      *
628      * @param v Vector with which outer product should be computed.
629      * @return the matrix outer product between this instance and {@code v}.
630      */
631     public RealMatrix outerProduct(RealVector v) {
632         final int m = this.getDimension();
633         final int n = v.getDimension();
634         final RealMatrix product;
635         if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
636             product = new OpenMapRealMatrix(m, n);
637         } else {
638             product = new Array2DRowRealMatrix(m, n);
639         }
640         for (int i = 0; i < m; i++) {
641             for (int j = 0; j < n; j++) {
642                 product.setEntry(i, j, this.getEntry(i) * v.getEntry(j));
643             }
644         }
645         return product;
646     }
647 
648     /**
649      * Find the orthogonal projection of this vector onto another vector.
650      *
651      * @param v vector onto which instance must be projected.
652      * @return projection of the instance onto {@code v}.
653      * @throws DimensionMismatchException if {@code v} is not the same size as
654      * {@code this} vector.
655      * @throws MathArithmeticException if {@code this} or {@code v} is the null
656      * vector
657      */
658     public RealVector projection(final RealVector v)
659         throws DimensionMismatchException, MathArithmeticException {
660         final double norm2 = v.dotProduct(v);
661         if (norm2 == 0.0) {
662             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
663         }
664         return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
665     }
666 
667     /**
668      * Set all elements to a single value.
669      *
670      * @param value Single value to set for all elements.
671      */
672     public void set(double value) {
673         Iterator<Entry> it = iterator();
674         while (it.hasNext()) {
675             final Entry e = it.next();
676             e.setValue(value);
677         }
678     }
679 
680     /**
681      * Convert the vector to an array of {@code double}s.
682      * The array is independent from this vector data: the elements
683      * are copied.
684      *
685      * @return an array containing a copy of the vector elements.
686      */
687     public double[] toArray() {
688         int dim = getDimension();
689         double[] values = new double[dim];
690         for (int i = 0; i < dim; i++) {
691             values[i] = getEntry(i);
692         }
693         return values;
694     }
695 
696     /**
697      * Creates a unit vector pointing in the direction of this vector.
698      * The instance is not changed by this method.
699      *
700      * @return a unit vector pointing in direction of this vector.
701      * @throws MathArithmeticException if the norm is zero.
702      */
703     public RealVector unitVector() throws MathArithmeticException {
704         final double norm = getNorm();
705         if (norm == 0) {
706             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
707         }
708         return mapDivide(norm);
709     }
710 
711     /**
712      * Converts this vector into a unit vector.
713      * The instance itself is changed by this method.
714      *
715      * @throws MathArithmeticException if the norm is zero.
716      */
717     public void unitize() throws MathArithmeticException {
718         final double norm = getNorm();
719         if (norm == 0) {
720             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
721         }
722         mapDivideToSelf(getNorm());
723     }
724 
725     /**
726      * Create a sparse iterator over the vector, which may omit some entries.
727      * The ommitted entries are either exact zeroes (for dense implementations)
728      * or are the entries which are not stored (for real sparse vectors).
729      * No guarantees are made about order of iteration.
730      *
731      * <p>Note: derived classes are required to return an {@link Iterator} that
732      * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
733      * returns {@code true}.</p>
734      *
735      * @return a sparse iterator.
736      */
737     public Iterator<Entry> sparseIterator() {
738         return new SparseEntryIterator();
739     }
740 
741     /**
742      * Generic dense iterator. Iteration is in increasing order
743      * of the vector index.
744      *
745      * <p>Note: derived classes are required to return an {@link Iterator} that
746      * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
747      * returns {@code true}.</p>
748      *
749      * @return a dense iterator.
750      */
751     public Iterator<Entry> iterator() {
752         final int dim = getDimension();
753         return new Iterator<Entry>() {
754 
755             /** Current index. */
756             private int i = 0;
757 
758             /** Current entry. */
759             private Entry e = new Entry();
760 
761             /** {@inheritDoc} */
762             public boolean hasNext() {
763                 return i < dim;
764             }
765 
766             /** {@inheritDoc} */
767             public Entry next() {
768                 if (i < dim) {
769                     e.setIndex(i++);
770                     return e;
771                 } else {
772                     throw new NoSuchElementException();
773                 }
774             }
775 
776             /**
777              * {@inheritDoc}
778              *
779              * @throws MathUnsupportedOperationException in all circumstances.
780              */
781             public void remove() throws MathUnsupportedOperationException {
782                 throw new MathUnsupportedOperationException();
783             }
784         };
785     }
786 
787     /**
788      * Acts as if implemented as:
789      * <pre>
790      *  return copy().mapToSelf(function);
791      * </pre>
792      * Returns a new vector. Does not change instance data.
793      *
794      * @param function Function to apply to each entry.
795      * @return a new vector.
796      */
797     public RealVector map(UnivariateFunction function) {
798         return copy().mapToSelf(function);
799     }
800 
801     /**
802      * Acts as if it is implemented as:
803      * <pre>
804      *  Entry e = null;
805      *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
806      *      e.setValue(function.value(e.getValue()));
807      *  }
808      * </pre>
809      * Entries of this vector are modified in-place by this method.
810      *
811      * @param function Function to apply to each entry.
812      * @return a reference to this vector.
813      */
814     public RealVector mapToSelf(UnivariateFunction function) {
815         Iterator<Entry> it = iterator();
816         while (it.hasNext()) {
817             final Entry e = it.next();
818             e.setValue(function.value(e.getValue()));
819         }
820         return this;
821     }
822 
823     /**
824      * Returns a new vector representing {@code a * this + b * y}, the linear
825      * combination of {@code this} and {@code y}.
826      * Returns a new vector. Does not change instance data.
827      *
828      * @param a Coefficient of {@code this}.
829      * @param b Coefficient of {@code y}.
830      * @param y Vector with which {@code this} is linearly combined.
831      * @return a vector containing {@code a * this[i] + b * y[i]} for all
832      * {@code i}.
833      * @throws DimensionMismatchException if {@code y} is not the same size as
834      * {@code this} vector.
835      */
836     public RealVector combine(double a, double b, RealVector y)
837         throws DimensionMismatchException {
838         return copy().combineToSelf(a, b, y);
839     }
840 
841     /**
842      * Updates {@code this} with the linear combination of {@code this} and
843      * {@code y}.
844      *
845      * @param a Weight of {@code this}.
846      * @param b Weight of {@code y}.
847      * @param y Vector with which {@code this} is linearly combined.
848      * @return {@code this}, with components equal to
849      * {@code a * this[i] + b * y[i]} for all {@code i}.
850      * @throws DimensionMismatchException if {@code y} is not the same size as
851      * {@code this} vector.
852      */
853     public RealVector combineToSelf(double a, double b, RealVector y)
854         throws DimensionMismatchException {
855         checkVectorDimensions(y);
856         for (int i = 0; i < getDimension(); i++) {
857             final double xi = getEntry(i);
858             final double yi = y.getEntry(i);
859             setEntry(i, a * xi + b * yi);
860         }
861         return this;
862     }
863 
864     /**
865      * Visits (but does not alter) all entries of this vector in default order
866      * (increasing index).
867      *
868      * @param visitor the visitor to be used to process the entries of this
869      * vector
870      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
871      * at the end of the walk
872      * @since 3.1
873      */
874     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
875         final int dim = getDimension();
876         visitor.start(dim, 0, dim - 1);
877         for (int i = 0; i < dim; i++) {
878             visitor.visit(i, getEntry(i));
879         }
880         return visitor.end();
881     }
882 
883     /**
884      * Visits (but does not alter) some entries of this vector in default order
885      * (increasing index).
886      *
887      * @param visitor visitor to be used to process the entries of this vector
888      * @param start the index of the first entry to be visited
889      * @param end the index of the last entry to be visited (inclusive)
890      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
891      * at the end of the walk
892      * @throws NumberIsTooSmallException if {@code end < start}.
893      * @throws OutOfRangeException if the indices are not valid.
894      * @since 3.1
895      */
896     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
897                                      final int start, final int end)
898         throws NumberIsTooSmallException, OutOfRangeException {
899         checkIndices(start, end);
900         visitor.start(getDimension(), start, end);
901         for (int i = start; i <= end; i++) {
902             visitor.visit(i, getEntry(i));
903         }
904         return visitor.end();
905     }
906 
907     /**
908      * Visits (but does not alter) all entries of this vector in optimized
909      * order. The order in which the entries are visited is selected so as to
910      * lead to the most efficient implementation; it might depend on the
911      * concrete implementation of this abstract class.
912      *
913      * @param visitor the visitor to be used to process the entries of this
914      * vector
915      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
916      * at the end of the walk
917      * @since 3.1
918      */
919     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
920         return walkInDefaultOrder(visitor);
921     }
922 
923     /**
924      * Visits (but does not alter) some entries of this vector in optimized
925      * order. The order in which the entries are visited is selected so as to
926      * lead to the most efficient implementation; it might depend on the
927      * concrete implementation of this abstract class.
928      *
929      * @param visitor visitor to be used to process the entries of this vector
930      * @param start the index of the first entry to be visited
931      * @param end the index of the last entry to be visited (inclusive)
932      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
933      * at the end of the walk
934      * @throws NumberIsTooSmallException if {@code end < start}.
935      * @throws OutOfRangeException if the indices are not valid.
936      * @since 3.1
937      */
938     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
939                                        final int start, final int end)
940         throws NumberIsTooSmallException, OutOfRangeException {
941         return walkInDefaultOrder(visitor, start, end);
942     }
943 
944     /**
945      * Visits (and possibly alters) all entries of this vector in default order
946      * (increasing index).
947      *
948      * @param visitor the visitor to be used to process and modify the entries
949      * of this vector
950      * @return the value returned by {@link RealVectorChangingVisitor#end()}
951      * at the end of the walk
952      * @since 3.1
953      */
954     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
955         final int dim = getDimension();
956         visitor.start(dim, 0, dim - 1);
957         for (int i = 0; i < dim; i++) {
958             setEntry(i, visitor.visit(i, getEntry(i)));
959         }
960         return visitor.end();
961     }
962 
963     /**
964      * Visits (and possibly alters) some entries of this vector in default order
965      * (increasing index).
966      *
967      * @param visitor visitor to be used to process the entries of this vector
968      * @param start the index of the first entry to be visited
969      * @param end the index of the last entry to be visited (inclusive)
970      * @return the value returned by {@link RealVectorChangingVisitor#end()}
971      * at the end of the walk
972      * @throws NumberIsTooSmallException if {@code end < start}.
973      * @throws OutOfRangeException if the indices are not valid.
974      * @since 3.1
975      */
976     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
977                               final int start, final int end)
978         throws NumberIsTooSmallException, OutOfRangeException {
979         checkIndices(start, end);
980         visitor.start(getDimension(), start, end);
981         for (int i = start; i <= end; i++) {
982             setEntry(i, visitor.visit(i, getEntry(i)));
983         }
984         return visitor.end();
985     }
986 
987     /**
988      * Visits (and possibly alters) all entries of this vector in optimized
989      * order. The order in which the entries are visited is selected so as to
990      * lead to the most efficient implementation; it might depend on the
991      * concrete implementation of this abstract class.
992      *
993      * @param visitor the visitor to be used to process the entries of this
994      * vector
995      * @return the value returned by {@link RealVectorChangingVisitor#end()}
996      * at the end of the walk
997      * @since 3.1
998      */
999     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
1000         return walkInDefaultOrder(visitor);
1001     }
1002 
1003     /**
1004      * Visits (and possibly change) some entries of this vector in optimized
1005      * order. The order in which the entries are visited is selected so as to
1006      * lead to the most efficient implementation; it might depend on the
1007      * concrete implementation of this abstract class.
1008      *
1009      * @param visitor visitor to be used to process the entries of this vector
1010      * @param start the index of the first entry to be visited
1011      * @param end the index of the last entry to be visited (inclusive)
1012      * @return the value returned by {@link RealVectorChangingVisitor#end()}
1013      * at the end of the walk
1014      * @throws NumberIsTooSmallException if {@code end < start}.
1015      * @throws OutOfRangeException if the indices are not valid.
1016      * @since 3.1
1017      */
1018     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
1019                                        final int start, final int end)
1020         throws NumberIsTooSmallException, OutOfRangeException {
1021         return walkInDefaultOrder(visitor, start, end);
1022     }
1023 
1024     /** An entry in the vector. */
1025     protected class Entry {
1026         /** Index of this entry. */
1027         private int index;
1028 
1029         /** Simple constructor. */
1030         public Entry() {
1031             setIndex(0);
1032         }
1033 
1034         /**
1035          * Get the value of the entry.
1036          *
1037          * @return the value of the entry.
1038          */
1039         public double getValue() {
1040             return getEntry(getIndex());
1041         }
1042 
1043         /**
1044          * Set the value of the entry.
1045          *
1046          * @param value New value for the entry.
1047          */
1048         public void setValue(double value) {
1049             setEntry(getIndex(), value);
1050         }
1051 
1052         /**
1053          * Get the index of the entry.
1054          *
1055          * @return the index of the entry.
1056          */
1057         public int getIndex() {
1058             return index;
1059         }
1060 
1061         /**
1062          * Set the index of the entry.
1063          *
1064          * @param index New index for the entry.
1065          */
1066         public void setIndex(int index) {
1067             this.index = index;
1068         }
1069     }
1070 
1071     /**
1072      * <p>
1073      * Test for the equality of two real vectors. If all coordinates of two real
1074      * vectors are exactly the same, and none are {@code NaN}, the two real
1075      * vectors are considered to be equal. {@code NaN} coordinates are
1076      * considered to affect globally the vector and be equals to each other -
1077      * i.e, if either (or all) coordinates of the real vector are equal to
1078      * {@code NaN}, the real vector is equal to a vector with all {@code NaN}
1079      * coordinates.
1080      * </p>
1081      * <p>
1082      * This method <em>must</em> be overriden by concrete subclasses of
1083      * {@link RealVector} (the current implementation throws an exception).
1084      * </p>
1085      *
1086      * @param other Object to test for equality.
1087      * @return {@code true} if two vector objects are equal, {@code false} if
1088      * {@code other} is null, not an instance of {@code RealVector}, or
1089      * not equal to this {@code RealVector} instance.
1090      * @throws MathUnsupportedOperationException if this method is not
1091      * overridden.
1092      */
1093     @Override
1094     public boolean equals(Object other)
1095         throws MathUnsupportedOperationException {
1096         throw new MathUnsupportedOperationException();
1097     }
1098 
1099     /**
1100      * {@inheritDoc}. This method <em>must</em> be overriden by concrete
1101      * subclasses of {@link RealVector} (current implementation throws an
1102      * exception).
1103      *
1104      * @throws MathUnsupportedOperationException if this method is not
1105      * overridden.
1106      */
1107     @Override
1108     public int hashCode() throws MathUnsupportedOperationException {
1109         throw new MathUnsupportedOperationException();
1110     }
1111 
1112     /**
1113      * This class should rarely be used, but is here to provide
1114      * a default implementation of sparseIterator(), which is implemented
1115      * by walking over the entries, skipping those that are zero.
1116      *
1117      * Concrete subclasses which are SparseVector implementations should
1118      * make their own sparse iterator, rather than using this one.
1119      *
1120      * This implementation might be useful for ArrayRealVector, when expensive
1121      * operations which preserve the default value are to be done on the entries,
1122      * and the fraction of non-default values is small (i.e. someone took a
1123      * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
1124 
1125      */
1126     protected class SparseEntryIterator implements Iterator<Entry> {
1127         /** Dimension of the vector. */
1128         private final int dim;
1129         /** Last entry returned by {@link #next()}. */
1130         private Entry current;
1131         /** Next entry for {@link #next()} to return. */
1132         private Entry next;
1133 
1134         /** Simple constructor. */
1135         protected SparseEntryIterator() {
1136             dim = getDimension();
1137             current = new Entry();
1138             next = new Entry();
1139             if (next.getValue() == 0) {
1140                 advance(next);
1141             }
1142         }
1143 
1144         /**
1145          * Advance an entry up to the next nonzero one.
1146          *
1147          * @param e entry to advance.
1148          */
1149         protected void advance(Entry e) {
1150             if (e == null) {
1151                 return;
1152             }
1153             do {
1154                 e.setIndex(e.getIndex() + 1);
1155             } while (e.getIndex() < dim && e.getValue() == 0);
1156             if (e.getIndex() >= dim) {
1157                 e.setIndex(-1);
1158             }
1159         }
1160 
1161         /** {@inheritDoc} */
1162         public boolean hasNext() {
1163             return next.getIndex() >= 0;
1164         }
1165 
1166         /** {@inheritDoc} */
1167         public Entry next() {
1168             int index = next.getIndex();
1169             if (index < 0) {
1170                 throw new NoSuchElementException();
1171             }
1172             current.setIndex(index);
1173             advance(next);
1174             return current;
1175         }
1176 
1177         /**
1178          * {@inheritDoc}
1179          *
1180          * @throws MathUnsupportedOperationException in all circumstances.
1181          */
1182         public void remove() throws MathUnsupportedOperationException {
1183             throw new MathUnsupportedOperationException();
1184         }
1185     }
1186 
1187     /**
1188      * Returns an unmodifiable view of the specified vector.
1189      * The returned vector has read-only access. An attempt to modify it will
1190      * result in a {@link MathUnsupportedOperationException}. However, the
1191      * returned vector is <em>not</em> immutable, since any modification of
1192      * {@code v} will also change the returned view.
1193      * For example, in the following piece of code
1194      * <pre>
1195      *     RealVector v = new ArrayRealVector(2);
1196      *     RealVector w = RealVector.unmodifiableRealVector(v);
1197      *     v.setEntry(0, 1.2);
1198      *     v.setEntry(1, -3.4);
1199      * </pre>
1200      * the changes will be seen in the {@code w} view of {@code v}.
1201      *
1202      * @param v Vector for which an unmodifiable view is to be returned.
1203      * @return an unmodifiable view of {@code v}.
1204      */
1205     public static RealVector unmodifiableRealVector(final RealVector v) {
1206         /**
1207          * This anonymous class is an implementation of {@link RealVector}
1208          * with read-only access.
1209          * It wraps any {@link RealVector}, and exposes all methods which
1210          * do not modify it. Invoking methods which should normally result
1211          * in the modification of the calling {@link RealVector} results in
1212          * a {@link MathUnsupportedOperationException}. It should be noted
1213          * that {@link UnmodifiableVector} is <em>not</em> immutable.
1214          */
1215         return new RealVector() {
1216             /**
1217              * {@inheritDoc}
1218              *
1219              * @throws MathUnsupportedOperationException in all circumstances.
1220              */
1221             @Override
1222             public RealVector mapToSelf(UnivariateFunction function)
1223                 throws MathUnsupportedOperationException {
1224                 throw new MathUnsupportedOperationException();
1225             }
1226 
1227             /** {@inheritDoc} */
1228             @Override
1229             public RealVector map(UnivariateFunction function) {
1230                 return v.map(function);
1231             }
1232 
1233             /** {@inheritDoc} */
1234             @Override
1235             public Iterator<Entry> iterator() {
1236                 final Iterator<Entry> i = v.iterator();
1237                 return new Iterator<Entry>() {
1238                     /** The current entry. */
1239                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1240 
1241                     /** {@inheritDoc} */
1242                     public boolean hasNext() {
1243                         return i.hasNext();
1244                     }
1245 
1246                     /** {@inheritDoc} */
1247                     public Entry next() {
1248                         e.setIndex(i.next().getIndex());
1249                         return e;
1250                     }
1251 
1252                     /**
1253                      * {@inheritDoc}
1254                      *
1255                      * @throws MathUnsupportedOperationException in all
1256                      * circumstances.
1257                      */
1258                     public void remove() throws MathUnsupportedOperationException {
1259                         throw new MathUnsupportedOperationException();
1260                     }
1261                 };
1262             }
1263 
1264             /** {@inheritDoc} */
1265             @Override
1266             public Iterator<Entry> sparseIterator() {
1267                 final Iterator<Entry> i = v.sparseIterator();
1268 
1269                 return new Iterator<Entry>() {
1270                     /** The current entry. */
1271                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1272 
1273                     /** {@inheritDoc} */
1274                     public boolean hasNext() {
1275                         return i.hasNext();
1276                     }
1277 
1278                     /** {@inheritDoc} */
1279                     public Entry next() {
1280                         e.setIndex(i.next().getIndex());
1281                         return e;
1282                     }
1283 
1284                     /**
1285                      * {@inheritDoc}
1286                      *
1287                      * @throws MathUnsupportedOperationException in all
1288                      * circumstances.
1289                      */
1290                     public void remove()
1291                         throws MathUnsupportedOperationException {
1292                         throw new MathUnsupportedOperationException();
1293                     }
1294                 };
1295             }
1296 
1297             /** {@inheritDoc} */
1298             @Override
1299             public RealVector copy() {
1300                 return v.copy();
1301             }
1302 
1303             /** {@inheritDoc} */
1304             @Override
1305             public RealVector add(RealVector w)
1306                 throws DimensionMismatchException {
1307                 return v.add(w);
1308             }
1309 
1310             /** {@inheritDoc} */
1311             @Override
1312             public RealVector subtract(RealVector w)
1313                 throws DimensionMismatchException {
1314                 return v.subtract(w);
1315             }
1316 
1317             /** {@inheritDoc} */
1318             @Override
1319             public RealVector mapAdd(double d) {
1320                 return v.mapAdd(d);
1321             }
1322 
1323             /**
1324              * {@inheritDoc}
1325              *
1326              * @throws MathUnsupportedOperationException in all
1327              * circumstances.
1328              */
1329             @Override
1330             public RealVector mapAddToSelf(double d)
1331                 throws MathUnsupportedOperationException {
1332                 throw new MathUnsupportedOperationException();
1333             }
1334 
1335             /** {@inheritDoc} */
1336             @Override
1337             public RealVector mapSubtract(double d) {
1338                 return v.mapSubtract(d);
1339             }
1340 
1341             /**
1342              * {@inheritDoc}
1343              *
1344              * @throws MathUnsupportedOperationException in all
1345              * circumstances.
1346              */
1347             @Override
1348             public RealVector mapSubtractToSelf(double d)
1349                 throws MathUnsupportedOperationException {
1350                 throw new MathUnsupportedOperationException();
1351             }
1352 
1353             /** {@inheritDoc} */
1354             @Override
1355             public RealVector mapMultiply(double d) {
1356                 return v.mapMultiply(d);
1357             }
1358 
1359             /**
1360              * {@inheritDoc}
1361              *
1362              * @throws MathUnsupportedOperationException in all
1363              * circumstances.
1364              */
1365             @Override
1366             public RealVector mapMultiplyToSelf(double d)
1367                 throws MathUnsupportedOperationException {
1368                 throw new MathUnsupportedOperationException();
1369             }
1370 
1371             /** {@inheritDoc} */
1372             @Override
1373             public RealVector mapDivide(double d) {
1374                 return v.mapDivide(d);
1375             }
1376 
1377             /**
1378              * {@inheritDoc}
1379              *
1380              * @throws MathUnsupportedOperationException in all
1381              * circumstances.
1382              */
1383             @Override
1384             public RealVector mapDivideToSelf(double d)
1385                 throws MathUnsupportedOperationException {
1386                 throw new MathUnsupportedOperationException();
1387             }
1388 
1389             /** {@inheritDoc} */
1390             @Override
1391             public RealVector ebeMultiply(RealVector w)
1392                 throws DimensionMismatchException {
1393                 return v.ebeMultiply(w);
1394             }
1395 
1396             /** {@inheritDoc} */
1397             @Override
1398             public RealVector ebeDivide(RealVector w)
1399                 throws DimensionMismatchException {
1400                 return v.ebeDivide(w);
1401             }
1402 
1403             /** {@inheritDoc} */
1404             @Override
1405             public double dotProduct(RealVector w)
1406                 throws DimensionMismatchException {
1407                 return v.dotProduct(w);
1408             }
1409 
1410             /** {@inheritDoc} */
1411             @Override
1412             public double cosine(RealVector w)
1413                 throws DimensionMismatchException, MathArithmeticException {
1414                 return v.cosine(w);
1415             }
1416 
1417             /** {@inheritDoc} */
1418             @Override
1419             public double getNorm() {
1420                 return v.getNorm();
1421             }
1422 
1423             /** {@inheritDoc} */
1424             @Override
1425             public double getL1Norm() {
1426                 return v.getL1Norm();
1427             }
1428 
1429             /** {@inheritDoc} */
1430             @Override
1431             public double getLInfNorm() {
1432                 return v.getLInfNorm();
1433             }
1434 
1435             /** {@inheritDoc} */
1436             @Override
1437             public double getDistance(RealVector w)
1438                 throws DimensionMismatchException {
1439                 return v.getDistance(w);
1440             }
1441 
1442             /** {@inheritDoc} */
1443             @Override
1444             public double getL1Distance(RealVector w)
1445                 throws DimensionMismatchException {
1446                 return v.getL1Distance(w);
1447             }
1448 
1449             /** {@inheritDoc} */
1450             @Override
1451             public double getLInfDistance(RealVector w)
1452                 throws DimensionMismatchException {
1453                 return v.getLInfDistance(w);
1454             }
1455 
1456             /** {@inheritDoc} */
1457             @Override
1458             public RealVector unitVector() throws MathArithmeticException {
1459                 return v.unitVector();
1460             }
1461 
1462             /**
1463              * {@inheritDoc}
1464              *
1465              * @throws MathUnsupportedOperationException in all
1466              * circumstances.
1467              */
1468             @Override
1469             public void unitize() throws MathUnsupportedOperationException {
1470                 throw new MathUnsupportedOperationException();
1471             }
1472 
1473             /** {@inheritDoc} */
1474             @Override
1475             public RealMatrix outerProduct(RealVector w) {
1476                 return v.outerProduct(w);
1477             }
1478 
1479             /** {@inheritDoc} */
1480             @Override
1481             public double getEntry(int index) throws OutOfRangeException {
1482                 return v.getEntry(index);
1483             }
1484 
1485             /**
1486              * {@inheritDoc}
1487              *
1488              * @throws MathUnsupportedOperationException in all
1489              * circumstances.
1490              */
1491             @Override
1492             public void setEntry(int index, double value)
1493                 throws MathUnsupportedOperationException {
1494                 throw new MathUnsupportedOperationException();
1495             }
1496 
1497             /**
1498              * {@inheritDoc}
1499              *
1500              * @throws MathUnsupportedOperationException in all
1501              * circumstances.
1502              */
1503             @Override
1504             public void addToEntry(int index, double value)
1505                 throws MathUnsupportedOperationException {
1506                 throw new MathUnsupportedOperationException();
1507             }
1508 
1509             /** {@inheritDoc} */
1510             @Override
1511             public int getDimension() {
1512                 return v.getDimension();
1513             }
1514 
1515             /** {@inheritDoc} */
1516             @Override
1517             public RealVector append(RealVector w) {
1518                 return v.append(w);
1519             }
1520 
1521             /** {@inheritDoc} */
1522             @Override
1523             public RealVector append(double d) {
1524                 return v.append(d);
1525             }
1526 
1527             /** {@inheritDoc} */
1528             @Override
1529             public RealVector getSubVector(int index, int n)
1530                 throws OutOfRangeException, NotPositiveException {
1531                 return v.getSubVector(index, n);
1532             }
1533 
1534             /**
1535              * {@inheritDoc}
1536              *
1537              * @throws MathUnsupportedOperationException in all
1538              * circumstances.
1539              */
1540             @Override
1541             public void setSubVector(int index, RealVector w)
1542                 throws MathUnsupportedOperationException {
1543                 throw new MathUnsupportedOperationException();
1544             }
1545 
1546             /**
1547              * {@inheritDoc}
1548              *
1549              * @throws MathUnsupportedOperationException in all
1550              * circumstances.
1551              */
1552             @Override
1553             public void set(double value)
1554                 throws MathUnsupportedOperationException {
1555                 throw new MathUnsupportedOperationException();
1556             }
1557 
1558             /** {@inheritDoc} */
1559             @Override
1560             public double[] toArray() {
1561                 return v.toArray();
1562             }
1563 
1564             /** {@inheritDoc} */
1565             @Override
1566             public boolean isNaN() {
1567                 return v.isNaN();
1568             }
1569 
1570             /** {@inheritDoc} */
1571             @Override
1572             public boolean isInfinite() {
1573                 return v.isInfinite();
1574             }
1575 
1576             /** {@inheritDoc} */
1577             @Override
1578             public RealVector combine(double a, double b, RealVector y)
1579                 throws DimensionMismatchException {
1580                 return v.combine(a, b, y);
1581             }
1582 
1583             /**
1584              * {@inheritDoc}
1585              *
1586              * @throws MathUnsupportedOperationException in all
1587              * circumstances.
1588              */
1589             @Override
1590             public RealVector combineToSelf(double a, double b, RealVector y)
1591                 throws MathUnsupportedOperationException {
1592                 throw new MathUnsupportedOperationException();
1593             }
1594 
1595             /** An entry in the vector. */
1596             class UnmodifiableEntry extends Entry {
1597                 /** {@inheritDoc} */
1598                 @Override
1599                 public double getValue() {
1600                     return v.getEntry(getIndex());
1601                 }
1602 
1603                 /**
1604                  * {@inheritDoc}
1605                  *
1606                  * @throws MathUnsupportedOperationException in all
1607                  * circumstances.
1608                  */
1609                 @Override
1610                 public void setValue(double value)
1611                     throws MathUnsupportedOperationException {
1612                     throw new MathUnsupportedOperationException();
1613                 }
1614             }
1615         };
1616     }
1617 }