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.math4.legacy.linear;
19  
20  import java.util.Iterator;
21  import java.util.NoSuchElementException;
22  
23  import org.apache.commons.math4.legacy.analysis.FunctionUtils;
24  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
25  import org.apache.commons.math4.legacy.analysis.function.Add;
26  import org.apache.commons.math4.legacy.analysis.function.Divide;
27  import org.apache.commons.math4.legacy.analysis.function.Multiply;
28  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
29  import org.apache.commons.math4.legacy.exception.MathArithmeticException;
30  import org.apache.commons.math4.legacy.exception.MathUnsupportedOperationException;
31  import org.apache.commons.math4.legacy.exception.NotPositiveException;
32  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
33  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
34  import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
35  import org.apache.commons.math4.core.jdkmath.JdkMath;
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 JdkMath.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 JdkMath.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 += JdkMath.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 = JdkMath.max(norm, JdkMath.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 += JdkMath.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 = JdkMath.max(JdkMath.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;
757 
758             /** Current entry. */
759             private Entry e = new Entry();
760 
761             /** {@inheritDoc} */
762             @Override
763             public boolean hasNext() {
764                 return i < dim;
765             }
766 
767             /** {@inheritDoc} */
768             @Override
769             public Entry next() {
770                 if (i < dim) {
771                     e.setIndex(i++);
772                     return e;
773                 } else {
774                     throw new NoSuchElementException();
775                 }
776             }
777 
778             /**
779              * {@inheritDoc}
780              *
781              * @throws MathUnsupportedOperationException in all circumstances.
782              */
783             @Override
784             public void remove() throws MathUnsupportedOperationException {
785                 throw new MathUnsupportedOperationException();
786             }
787         };
788     }
789 
790     /**
791      * Acts as if implemented as:
792      * <pre>
793      *  return copy().mapToSelf(function);
794      * </pre>
795      * Returns a new vector. Does not change instance data.
796      *
797      * @param function Function to apply to each entry.
798      * @return a new vector.
799      */
800     public RealVector map(UnivariateFunction function) {
801         return copy().mapToSelf(function);
802     }
803 
804     /**
805      * Acts as if it is implemented as:
806      * {@code
807      *  Entry e = null;
808      *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
809      *      e.setValue(function.value(e.getValue()));
810      *  }
811      * }
812      * Entries of this vector are modified in-place by this method.
813      *
814      * @param function Function to apply to each entry.
815      * @return a reference to this vector.
816      */
817     public RealVector mapToSelf(UnivariateFunction function) {
818         Iterator<Entry> it = iterator();
819         while (it.hasNext()) {
820             final Entry e = it.next();
821             e.setValue(function.value(e.getValue()));
822         }
823         return this;
824     }
825 
826     /**
827      * Returns a new vector representing {@code a * this + b * y}, the linear
828      * combination of {@code this} and {@code y}.
829      * Returns a new vector. Does not change instance data.
830      *
831      * @param a Coefficient of {@code this}.
832      * @param b Coefficient of {@code y}.
833      * @param y Vector with which {@code this} is linearly combined.
834      * @return a vector containing {@code a * this[i] + b * y[i]} for all
835      * {@code i}.
836      * @throws DimensionMismatchException if {@code y} is not the same size as
837      * {@code this} vector.
838      */
839     public RealVector combine(double a, double b, RealVector y)
840         throws DimensionMismatchException {
841         return copy().combineToSelf(a, b, y);
842     }
843 
844     /**
845      * Updates {@code this} with the linear combination of {@code this} and
846      * {@code y}.
847      *
848      * @param a Weight of {@code this}.
849      * @param b Weight of {@code y}.
850      * @param y Vector with which {@code this} is linearly combined.
851      * @return {@code this}, with components equal to
852      * {@code a * this[i] + b * y[i]} for all {@code i}.
853      * @throws DimensionMismatchException if {@code y} is not the same size as
854      * {@code this} vector.
855      */
856     public RealVector combineToSelf(double a, double b, RealVector y)
857         throws DimensionMismatchException {
858         checkVectorDimensions(y);
859         for (int i = 0; i < getDimension(); i++) {
860             final double xi = getEntry(i);
861             final double yi = y.getEntry(i);
862             setEntry(i, a * xi + b * yi);
863         }
864         return this;
865     }
866 
867     /**
868      * Visits (but does not alter) all entries of this vector in default order
869      * (increasing index).
870      *
871      * @param visitor the visitor to be used to process the entries of this
872      * vector
873      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
874      * at the end of the walk
875      * @since 3.1
876      */
877     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
878         final int dim = getDimension();
879         visitor.start(dim, 0, dim - 1);
880         for (int i = 0; i < dim; i++) {
881             visitor.visit(i, getEntry(i));
882         }
883         return visitor.end();
884     }
885 
886     /**
887      * Visits (but does not alter) some entries of this vector in default order
888      * (increasing index).
889      *
890      * @param visitor visitor to be used to process the entries of this vector
891      * @param start the index of the first entry to be visited
892      * @param end the index of the last entry to be visited (inclusive)
893      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
894      * at the end of the walk
895      * @throws NumberIsTooSmallException if {@code end < start}.
896      * @throws OutOfRangeException if the indices are not valid.
897      * @since 3.1
898      */
899     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
900                                      final int start, final int end)
901         throws NumberIsTooSmallException, OutOfRangeException {
902         checkIndices(start, end);
903         visitor.start(getDimension(), start, end);
904         for (int i = start; i <= end; i++) {
905             visitor.visit(i, getEntry(i));
906         }
907         return visitor.end();
908     }
909 
910     /**
911      * Visits (but does not alter) all entries of this vector in optimized
912      * order. The order in which the entries are visited is selected so as to
913      * lead to the most efficient implementation; it might depend on the
914      * concrete implementation of this abstract class.
915      *
916      * @param visitor the visitor to be used to process the entries of this
917      * vector
918      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
919      * at the end of the walk
920      * @since 3.1
921      */
922     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
923         return walkInDefaultOrder(visitor);
924     }
925 
926     /**
927      * Visits (but does not alter) some entries of this vector in optimized
928      * order. The order in which the entries are visited is selected so as to
929      * lead to the most efficient implementation; it might depend on the
930      * concrete implementation of this abstract class.
931      *
932      * @param visitor visitor to be used to process the entries of this vector
933      * @param start the index of the first entry to be visited
934      * @param end the index of the last entry to be visited (inclusive)
935      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
936      * at the end of the walk
937      * @throws NumberIsTooSmallException if {@code end < start}.
938      * @throws OutOfRangeException if the indices are not valid.
939      * @since 3.1
940      */
941     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
942                                        final int start, final int end)
943         throws NumberIsTooSmallException, OutOfRangeException {
944         return walkInDefaultOrder(visitor, start, end);
945     }
946 
947     /**
948      * Visits (and possibly alters) all entries of this vector in default order
949      * (increasing index).
950      *
951      * @param visitor the visitor to be used to process and modify the entries
952      * of this vector
953      * @return the value returned by {@link RealVectorChangingVisitor#end()}
954      * at the end of the walk
955      * @since 3.1
956      */
957     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
958         final int dim = getDimension();
959         visitor.start(dim, 0, dim - 1);
960         for (int i = 0; i < dim; i++) {
961             setEntry(i, visitor.visit(i, getEntry(i)));
962         }
963         return visitor.end();
964     }
965 
966     /**
967      * Visits (and possibly alters) some entries of this vector in default order
968      * (increasing index).
969      *
970      * @param visitor visitor to be used to process the entries of this vector
971      * @param start the index of the first entry to be visited
972      * @param end the index of the last entry to be visited (inclusive)
973      * @return the value returned by {@link RealVectorChangingVisitor#end()}
974      * at the end of the walk
975      * @throws NumberIsTooSmallException if {@code end < start}.
976      * @throws OutOfRangeException if the indices are not valid.
977      * @since 3.1
978      */
979     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
980                               final int start, final int end)
981         throws NumberIsTooSmallException, OutOfRangeException {
982         checkIndices(start, end);
983         visitor.start(getDimension(), start, end);
984         for (int i = start; i <= end; i++) {
985             setEntry(i, visitor.visit(i, getEntry(i)));
986         }
987         return visitor.end();
988     }
989 
990     /**
991      * Visits (and possibly alters) all entries of this vector in optimized
992      * order. The order in which the entries are visited is selected so as to
993      * lead to the most efficient implementation; it might depend on the
994      * concrete implementation of this abstract class.
995      *
996      * @param visitor the visitor to be used to process the entries of this
997      * vector
998      * @return the value returned by {@link RealVectorChangingVisitor#end()}
999      * at the end of the walk
1000      * @since 3.1
1001      */
1002     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
1003         return walkInDefaultOrder(visitor);
1004     }
1005 
1006     /**
1007      * Visits (and possibly change) some entries of this vector in optimized
1008      * order. The order in which the entries are visited is selected so as to
1009      * lead to the most efficient implementation; it might depend on the
1010      * concrete implementation of this abstract class.
1011      *
1012      * @param visitor visitor to be used to process the entries of this vector
1013      * @param start the index of the first entry to be visited
1014      * @param end the index of the last entry to be visited (inclusive)
1015      * @return the value returned by {@link RealVectorChangingVisitor#end()}
1016      * at the end of the walk
1017      * @throws NumberIsTooSmallException if {@code end < start}.
1018      * @throws OutOfRangeException if the indices are not valid.
1019      * @since 3.1
1020      */
1021     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
1022                                        final int start, final int end)
1023         throws NumberIsTooSmallException, OutOfRangeException {
1024         return walkInDefaultOrder(visitor, start, end);
1025     }
1026 
1027     /** An entry in the vector. */
1028     protected class Entry {
1029         /** Index of this entry. */
1030         private int index;
1031 
1032         /** Simple constructor. */
1033         public Entry() {
1034             setIndex(0);
1035         }
1036 
1037         /**
1038          * Get the value of the entry.
1039          *
1040          * @return the value of the entry.
1041          */
1042         public double getValue() {
1043             return getEntry(getIndex());
1044         }
1045 
1046         /**
1047          * Set the value of the entry.
1048          *
1049          * @param value New value for the entry.
1050          */
1051         public void setValue(double value) {
1052             setEntry(getIndex(), value);
1053         }
1054 
1055         /**
1056          * Get the index of the entry.
1057          *
1058          * @return the index of the entry.
1059          */
1060         public int getIndex() {
1061             return index;
1062         }
1063 
1064         /**
1065          * Set the index of the entry.
1066          *
1067          * @param index New index for the entry.
1068          */
1069         public void setIndex(int index) {
1070             this.index = index;
1071         }
1072     }
1073 
1074     /**
1075      * <p>
1076      * Test for the equality of two real vectors. If all coordinates of two real
1077      * vectors are exactly the same, and none are {@code NaN}, the two real
1078      * vectors are considered to be equal. {@code NaN} coordinates are
1079      * considered to affect globally the vector and be equals to each other -
1080      * i.e, if either (or all) coordinates of the real vector are equal to
1081      * {@code NaN}, the real vector is equal to a vector with all {@code NaN}
1082      * coordinates.
1083      * </p>
1084      * <p>
1085      * This method <em>must</em> be overridden by concrete subclasses of
1086      * {@link RealVector} (the current implementation throws an exception).
1087      * </p>
1088      *
1089      * @param other Object to test for equality.
1090      * @return {@code true} if two vector objects are equal, {@code false} if
1091      * {@code other} is null, not an instance of {@code RealVector}, or
1092      * not equal to this {@code RealVector} instance.
1093      * @throws MathUnsupportedOperationException if this method is not
1094      * overridden.
1095      */
1096     @Override
1097     public boolean equals(Object other)
1098         throws MathUnsupportedOperationException {
1099         throw new MathUnsupportedOperationException();
1100     }
1101 
1102     /**
1103      * {@inheritDoc}. This method <em>must</em> be overridden by concrete
1104      * subclasses of {@link RealVector} (current implementation throws an
1105      * exception).
1106      *
1107      * @throws MathUnsupportedOperationException if this method is not
1108      * overridden.
1109      */
1110     @Override
1111     public int hashCode() throws MathUnsupportedOperationException {
1112         throw new MathUnsupportedOperationException();
1113     }
1114 
1115     /**
1116      * This class should rarely be used, but is here to provide
1117      * a default implementation of sparseIterator(), which is implemented
1118      * by walking over the entries, skipping those that are zero.
1119      *
1120      * Concrete subclasses which are SparseVector implementations should
1121      * make their own sparse iterator, rather than using this one.
1122      *
1123      * This implementation might be useful for ArrayRealVector, when expensive
1124      * operations which preserve the default value are to be done on the entries,
1125      * and the fraction of non-default values is small (i.e. someone took a
1126      * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
1127 
1128      */
1129     protected class SparseEntryIterator implements Iterator<Entry> {
1130         /** Dimension of the vector. */
1131         private final int dim;
1132         /** Last entry returned by {@link #next()}. */
1133         private Entry current;
1134         /** Next entry for {@link #next()} to return. */
1135         private Entry next;
1136 
1137         /** Simple constructor. */
1138         protected SparseEntryIterator() {
1139             dim = getDimension();
1140             current = new Entry();
1141             next = new Entry();
1142             if (next.getValue() == 0) {
1143                 advance(next);
1144             }
1145         }
1146 
1147         /**
1148          * Advance an entry up to the next nonzero one.
1149          *
1150          * @param e entry to advance.
1151          */
1152         protected void advance(Entry e) {
1153             if (e == null) {
1154                 return;
1155             }
1156             do {
1157                 e.setIndex(e.getIndex() + 1);
1158             } while (e.getIndex() < dim && e.getValue() == 0);
1159             if (e.getIndex() >= dim) {
1160                 e.setIndex(-1);
1161             }
1162         }
1163 
1164         /** {@inheritDoc} */
1165         @Override
1166         public boolean hasNext() {
1167             return next.getIndex() >= 0;
1168         }
1169 
1170         /** {@inheritDoc} */
1171         @Override
1172         public Entry next() {
1173             int index = next.getIndex();
1174             if (index < 0) {
1175                 throw new NoSuchElementException();
1176             }
1177             current.setIndex(index);
1178             advance(next);
1179             return current;
1180         }
1181 
1182         /**
1183          * {@inheritDoc}
1184          *
1185          * @throws MathUnsupportedOperationException in all circumstances.
1186          */
1187         @Override
1188         public void remove() throws MathUnsupportedOperationException {
1189             throw new MathUnsupportedOperationException();
1190         }
1191     }
1192 
1193     /**
1194      * Returns an unmodifiable view of the specified vector.
1195      * The returned vector has read-only access. An attempt to modify it will
1196      * result in a {@link MathUnsupportedOperationException}. However, the
1197      * returned vector is <em>not</em> immutable, since any modification of
1198      * {@code v} will also change the returned view.
1199      * For example, in the following piece of code
1200      * <pre>
1201      *     RealVector v = new ArrayRealVector(2);
1202      *     RealVector w = RealVector.unmodifiableRealVector(v);
1203      *     v.setEntry(0, 1.2);
1204      *     v.setEntry(1, -3.4);
1205      * </pre>
1206      * the changes will be seen in the {@code w} view of {@code v}.
1207      *
1208      * @param v Vector for which an unmodifiable view is to be returned.
1209      * @return an unmodifiable view of {@code v}.
1210      */
1211     public static RealVector unmodifiableRealVector(final RealVector v) {
1212         /*
1213          * This anonymous class is an implementation of {@link RealVector}
1214          * with read-only access.
1215          * It wraps any {@link RealVector}, and exposes all methods which
1216          * do not modify it. Invoking methods which should normally result
1217          * in the modification of the calling {@link RealVector} results in
1218          * a {@link MathUnsupportedOperationException}. It should be noted
1219          * that {@link UnmodifiableVector} is <em>not</em> immutable.
1220          */
1221         return new RealVector() {
1222             /**
1223              * {@inheritDoc}
1224              *
1225              * @throws MathUnsupportedOperationException in all circumstances.
1226              */
1227             @Override
1228             public RealVector mapToSelf(UnivariateFunction function)
1229                 throws MathUnsupportedOperationException {
1230                 throw new MathUnsupportedOperationException();
1231             }
1232 
1233             /** {@inheritDoc} */
1234             @Override
1235             public RealVector map(UnivariateFunction function) {
1236                 return v.map(function);
1237             }
1238 
1239             /** {@inheritDoc} */
1240             @Override
1241             public Iterator<Entry> iterator() {
1242                 final Iterator<Entry> i = v.iterator();
1243                 return new Iterator<Entry>() {
1244                     /** The current entry. */
1245                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1246 
1247                     /** {@inheritDoc} */
1248                     @Override
1249                     public boolean hasNext() {
1250                         return i.hasNext();
1251                     }
1252 
1253                     /** {@inheritDoc} */
1254                     @Override
1255                     public Entry next() {
1256                         e.setIndex(i.next().getIndex());
1257                         return e;
1258                     }
1259 
1260                     /**
1261                      * {@inheritDoc}
1262                      *
1263                      * @throws MathUnsupportedOperationException in all
1264                      * circumstances.
1265                      */
1266                     @Override
1267                     public void remove() throws MathUnsupportedOperationException {
1268                         throw new MathUnsupportedOperationException();
1269                     }
1270                 };
1271             }
1272 
1273             /** {@inheritDoc} */
1274             @Override
1275             public Iterator<Entry> sparseIterator() {
1276                 final Iterator<Entry> i = v.sparseIterator();
1277 
1278                 return new Iterator<Entry>() {
1279                     /** The current entry. */
1280                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1281 
1282                     /** {@inheritDoc} */
1283                     @Override
1284                     public boolean hasNext() {
1285                         return i.hasNext();
1286                     }
1287 
1288                     /** {@inheritDoc} */
1289                     @Override
1290                     public Entry next() {
1291                         e.setIndex(i.next().getIndex());
1292                         return e;
1293                     }
1294 
1295                     /**
1296                      * {@inheritDoc}
1297                      *
1298                      * @throws MathUnsupportedOperationException in all
1299                      * circumstances.
1300                      */
1301                     @Override
1302                     public void remove()
1303                         throws MathUnsupportedOperationException {
1304                         throw new MathUnsupportedOperationException();
1305                     }
1306                 };
1307             }
1308 
1309             /** {@inheritDoc} */
1310             @Override
1311             public RealVector copy() {
1312                 return v.copy();
1313             }
1314 
1315             /** {@inheritDoc} */
1316             @Override
1317             public RealVector add(RealVector w)
1318                 throws DimensionMismatchException {
1319                 return v.add(w);
1320             }
1321 
1322             /** {@inheritDoc} */
1323             @Override
1324             public RealVector subtract(RealVector w)
1325                 throws DimensionMismatchException {
1326                 return v.subtract(w);
1327             }
1328 
1329             /** {@inheritDoc} */
1330             @Override
1331             public RealVector mapAdd(double d) {
1332                 return v.mapAdd(d);
1333             }
1334 
1335             /**
1336              * {@inheritDoc}
1337              *
1338              * @throws MathUnsupportedOperationException in all
1339              * circumstances.
1340              */
1341             @Override
1342             public RealVector mapAddToSelf(double d)
1343                 throws MathUnsupportedOperationException {
1344                 throw new MathUnsupportedOperationException();
1345             }
1346 
1347             /** {@inheritDoc} */
1348             @Override
1349             public RealVector mapSubtract(double d) {
1350                 return v.mapSubtract(d);
1351             }
1352 
1353             /**
1354              * {@inheritDoc}
1355              *
1356              * @throws MathUnsupportedOperationException in all
1357              * circumstances.
1358              */
1359             @Override
1360             public RealVector mapSubtractToSelf(double d)
1361                 throws MathUnsupportedOperationException {
1362                 throw new MathUnsupportedOperationException();
1363             }
1364 
1365             /** {@inheritDoc} */
1366             @Override
1367             public RealVector mapMultiply(double d) {
1368                 return v.mapMultiply(d);
1369             }
1370 
1371             /**
1372              * {@inheritDoc}
1373              *
1374              * @throws MathUnsupportedOperationException in all
1375              * circumstances.
1376              */
1377             @Override
1378             public RealVector mapMultiplyToSelf(double d)
1379                 throws MathUnsupportedOperationException {
1380                 throw new MathUnsupportedOperationException();
1381             }
1382 
1383             /** {@inheritDoc} */
1384             @Override
1385             public RealVector mapDivide(double d) {
1386                 return v.mapDivide(d);
1387             }
1388 
1389             /**
1390              * {@inheritDoc}
1391              *
1392              * @throws MathUnsupportedOperationException in all
1393              * circumstances.
1394              */
1395             @Override
1396             public RealVector mapDivideToSelf(double d)
1397                 throws MathUnsupportedOperationException {
1398                 throw new MathUnsupportedOperationException();
1399             }
1400 
1401             /** {@inheritDoc} */
1402             @Override
1403             public RealVector ebeMultiply(RealVector w)
1404                 throws DimensionMismatchException {
1405                 return v.ebeMultiply(w);
1406             }
1407 
1408             /** {@inheritDoc} */
1409             @Override
1410             public RealVector ebeDivide(RealVector w)
1411                 throws DimensionMismatchException {
1412                 return v.ebeDivide(w);
1413             }
1414 
1415             /** {@inheritDoc} */
1416             @Override
1417             public double dotProduct(RealVector w)
1418                 throws DimensionMismatchException {
1419                 return v.dotProduct(w);
1420             }
1421 
1422             /** {@inheritDoc} */
1423             @Override
1424             public double cosine(RealVector w)
1425                 throws DimensionMismatchException, MathArithmeticException {
1426                 return v.cosine(w);
1427             }
1428 
1429             /** {@inheritDoc} */
1430             @Override
1431             public double getNorm() {
1432                 return v.getNorm();
1433             }
1434 
1435             /** {@inheritDoc} */
1436             @Override
1437             public double getL1Norm() {
1438                 return v.getL1Norm();
1439             }
1440 
1441             /** {@inheritDoc} */
1442             @Override
1443             public double getLInfNorm() {
1444                 return v.getLInfNorm();
1445             }
1446 
1447             /** {@inheritDoc} */
1448             @Override
1449             public double getDistance(RealVector w)
1450                 throws DimensionMismatchException {
1451                 return v.getDistance(w);
1452             }
1453 
1454             /** {@inheritDoc} */
1455             @Override
1456             public double getL1Distance(RealVector w)
1457                 throws DimensionMismatchException {
1458                 return v.getL1Distance(w);
1459             }
1460 
1461             /** {@inheritDoc} */
1462             @Override
1463             public double getLInfDistance(RealVector w)
1464                 throws DimensionMismatchException {
1465                 return v.getLInfDistance(w);
1466             }
1467 
1468             /** {@inheritDoc} */
1469             @Override
1470             public RealVector unitVector() throws MathArithmeticException {
1471                 return v.unitVector();
1472             }
1473 
1474             /**
1475              * {@inheritDoc}
1476              *
1477              * @throws MathUnsupportedOperationException in all
1478              * circumstances.
1479              */
1480             @Override
1481             public void unitize() throws MathUnsupportedOperationException {
1482                 throw new MathUnsupportedOperationException();
1483             }
1484 
1485             /** {@inheritDoc} */
1486             @Override
1487             public RealMatrix outerProduct(RealVector w) {
1488                 return v.outerProduct(w);
1489             }
1490 
1491             /** {@inheritDoc} */
1492             @Override
1493             public double getEntry(int index) throws OutOfRangeException {
1494                 return v.getEntry(index);
1495             }
1496 
1497             /**
1498              * {@inheritDoc}
1499              *
1500              * @throws MathUnsupportedOperationException in all
1501              * circumstances.
1502              */
1503             @Override
1504             public void setEntry(int index, double value)
1505                 throws MathUnsupportedOperationException {
1506                 throw new MathUnsupportedOperationException();
1507             }
1508 
1509             /**
1510              * {@inheritDoc}
1511              *
1512              * @throws MathUnsupportedOperationException in all
1513              * circumstances.
1514              */
1515             @Override
1516             public void addToEntry(int index, double value)
1517                 throws MathUnsupportedOperationException {
1518                 throw new MathUnsupportedOperationException();
1519             }
1520 
1521             /** {@inheritDoc} */
1522             @Override
1523             public int getDimension() {
1524                 return v.getDimension();
1525             }
1526 
1527             /** {@inheritDoc} */
1528             @Override
1529             public RealVector append(RealVector w) {
1530                 return v.append(w);
1531             }
1532 
1533             /** {@inheritDoc} */
1534             @Override
1535             public RealVector append(double d) {
1536                 return v.append(d);
1537             }
1538 
1539             /** {@inheritDoc} */
1540             @Override
1541             public RealVector getSubVector(int index, int n)
1542                 throws OutOfRangeException, NotPositiveException {
1543                 return v.getSubVector(index, n);
1544             }
1545 
1546             /**
1547              * {@inheritDoc}
1548              *
1549              * @throws MathUnsupportedOperationException in all
1550              * circumstances.
1551              */
1552             @Override
1553             public void setSubVector(int index, RealVector w)
1554                 throws MathUnsupportedOperationException {
1555                 throw new MathUnsupportedOperationException();
1556             }
1557 
1558             /**
1559              * {@inheritDoc}
1560              *
1561              * @throws MathUnsupportedOperationException in all
1562              * circumstances.
1563              */
1564             @Override
1565             public void set(double value)
1566                 throws MathUnsupportedOperationException {
1567                 throw new MathUnsupportedOperationException();
1568             }
1569 
1570             /** {@inheritDoc} */
1571             @Override
1572             public double[] toArray() {
1573                 return v.toArray();
1574             }
1575 
1576             /** {@inheritDoc} */
1577             @Override
1578             public boolean isNaN() {
1579                 return v.isNaN();
1580             }
1581 
1582             /** {@inheritDoc} */
1583             @Override
1584             public boolean isInfinite() {
1585                 return v.isInfinite();
1586             }
1587 
1588             /** {@inheritDoc} */
1589             @Override
1590             public RealVector combine(double a, double b, RealVector y)
1591                 throws DimensionMismatchException {
1592                 return v.combine(a, b, y);
1593             }
1594 
1595             /**
1596              * {@inheritDoc}
1597              *
1598              * @throws MathUnsupportedOperationException in all
1599              * circumstances.
1600              */
1601             @Override
1602             public RealVector combineToSelf(double a, double b, RealVector y)
1603                 throws MathUnsupportedOperationException {
1604                 throw new MathUnsupportedOperationException();
1605             }
1606 
1607             /** An entry in the vector. */
1608             class UnmodifiableEntry extends Entry {
1609                 /** {@inheritDoc} */
1610                 @Override
1611                 public double getValue() {
1612                     return v.getEntry(getIndex());
1613                 }
1614 
1615                 /**
1616                  * {@inheritDoc}
1617                  *
1618                  * @throws MathUnsupportedOperationException in all
1619                  * circumstances.
1620                  */
1621                 @Override
1622                 public void setValue(double value)
1623                     throws MathUnsupportedOperationException {
1624                     throw new MathUnsupportedOperationException();
1625                 }
1626             }
1627         };
1628     }
1629 }