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