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 1422313 2012-12-15 18:53:41Z psteitz $
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      * @deprecated As of version 3.1, this method is deprecated, and will be
347      * removed in version 4.0. This decision follows the discussion reported in
348      * <a href="https://issues.apache.org/jira/browse/MATH-803?focusedCommentId=13399150#comment-13399150">MATH-803</a>.
349      * Uses of this method involving sparse implementations of
350      * {@link RealVector} might lead to wrong results. Since there is no
351      * satisfactory correction to this bug, this method is deprecated. Users who
352      * want to preserve this feature are advised to implement
353      * {@link RealVectorPreservingVisitor} (possibly ignoring corner cases for
354      * the sake of efficiency).
355      */
356     @Deprecated
357     public abstract RealVector ebeDivide(RealVector v)
358         throws DimensionMismatchException;
359 
360     /**
361      * Element-by-element multiplication.
362      *
363      * @param v Vector by which instance elements must be multiplied
364      * @return a vector containing this[i] * v[i] for all i.
365      * @throws DimensionMismatchException if {@code v} is not the same size as
366      * {@code this} vector.
367      * @deprecated As of version 3.1, this method is deprecated, and will be
368      * removed in version 4.0. This decision follows the discussion reported in
369      * <a href="https://issues.apache.org/jira/browse/MATH-803?focusedCommentId=13399150#comment-13399150">MATH-803</a>.
370      * Uses of this method involving sparse implementations of
371      * {@link RealVector} might lead to wrong results. Since there is no
372      * satisfactory correction to this bug, this method is deprecated. Users who
373      * want to preserve this feature are advised to implement
374      * {@link RealVectorPreservingVisitor} (possibly ignoring corner cases for
375      * the sake of efficiency).
376      */
377     @Deprecated
378     public abstract RealVector ebeMultiply(RealVector v)
379         throws DimensionMismatchException;
380 
381     /**
382      * Distance between two vectors.
383      * <p>This method computes the distance consistent with the
384      * L<sub>2</sub> norm, i.e. the square root of the sum of
385      * element differences, or Euclidean distance.</p>
386      *
387      * @param v Vector to which distance is requested.
388      * @return the distance between two vectors.
389      * @throws DimensionMismatchException if {@code v} is not the same size as
390      * {@code this} vector.
391      * @see #getL1Distance(RealVector)
392      * @see #getLInfDistance(RealVector)
393      * @see #getNorm()
394      */
395     public double getDistance(RealVector v) throws DimensionMismatchException {
396         checkVectorDimensions(v);
397         double d = 0;
398         Iterator<Entry> it = iterator();
399         while (it.hasNext()) {
400             final Entry e = it.next();
401             final double diff = e.getValue() - v.getEntry(e.getIndex());
402             d += diff * diff;
403         }
404         return FastMath.sqrt(d);
405     }
406 
407     /**
408      * Returns the L<sub>2</sub> norm of the vector.
409      * <p>The L<sub>2</sub> norm is the root of the sum of
410      * the squared elements.</p>
411      *
412      * @return the norm.
413      * @see #getL1Norm()
414      * @see #getLInfNorm()
415      * @see #getDistance(RealVector)
416      */
417     public double getNorm() {
418         double sum = 0;
419         Iterator<Entry> it = iterator();
420         while (it.hasNext()) {
421             final Entry e = it.next();
422             final double value = e.getValue();
423             sum += value * value;
424         }
425         return FastMath.sqrt(sum);
426     }
427 
428     /**
429      * Returns the L<sub>1</sub> norm of the vector.
430      * <p>The L<sub>1</sub> norm is the sum of the absolute
431      * values of the elements.</p>
432      *
433      * @return the norm.
434      * @see #getNorm()
435      * @see #getLInfNorm()
436      * @see #getL1Distance(RealVector)
437      */
438     public double getL1Norm() {
439         double norm = 0;
440         Iterator<Entry> it = iterator();
441         while (it.hasNext()) {
442             final Entry e = it.next();
443             norm += FastMath.abs(e.getValue());
444         }
445         return norm;
446     }
447 
448     /**
449      * Returns the L<sub>&infin;</sub> norm of the vector.
450      * <p>The L<sub>&infin;</sub> norm is the max of the absolute
451      * values of the elements.</p>
452      *
453      * @return the norm.
454      * @see #getNorm()
455      * @see #getL1Norm()
456      * @see #getLInfDistance(RealVector)
457      */
458     public double getLInfNorm() {
459         double norm = 0;
460         Iterator<Entry> it = iterator();
461         while (it.hasNext()) {
462             final Entry e = it.next();
463             norm = FastMath.max(norm, FastMath.abs(e.getValue()));
464         }
465         return norm;
466     }
467 
468     /**
469      * Distance between two vectors.
470      * <p>This method computes the distance consistent with
471      * L<sub>1</sub> norm, i.e. the sum of the absolute values of
472      * the elements differences.</p>
473      *
474      * @param v Vector to which distance is requested.
475      * @return the distance between two vectors.
476      * @throws DimensionMismatchException if {@code v} is not the same size as
477      * {@code this} vector.
478      */
479     public double getL1Distance(RealVector v)
480         throws DimensionMismatchException {
481         checkVectorDimensions(v);
482         double d = 0;
483         Iterator<Entry> it = iterator();
484         while (it.hasNext()) {
485             final Entry e = it.next();
486             d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
487         }
488         return d;
489     }
490 
491     /**
492      * Distance between two vectors.
493      * <p>This method computes the distance consistent with
494      * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
495      * element differences.</p>
496      *
497      * @param v Vector to which distance is requested.
498      * @return the distance between two vectors.
499      * @throws DimensionMismatchException if {@code v} is not the same size as
500      * {@code this} vector.
501      * @see #getDistance(RealVector)
502      * @see #getL1Distance(RealVector)
503      * @see #getLInfNorm()
504      */
505     public double getLInfDistance(RealVector v)
506         throws DimensionMismatchException {
507         checkVectorDimensions(v);
508         double d = 0;
509         Iterator<Entry> it = iterator();
510         while (it.hasNext()) {
511             final Entry e = it.next();
512             d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
513         }
514         return d;
515     }
516 
517     /**
518      * Get the index of the minimum entry.
519      *
520      * @return the index of the minimum entry or -1 if vector length is 0
521      * or all entries are {@code NaN}.
522      */
523     public int getMinIndex() {
524         int minIndex    = -1;
525         double minValue = Double.POSITIVE_INFINITY;
526         Iterator<Entry> iterator = iterator();
527         while (iterator.hasNext()) {
528             final Entry entry = iterator.next();
529             if (entry.getValue() <= minValue) {
530                 minIndex = entry.getIndex();
531                 minValue = entry.getValue();
532             }
533         }
534         return minIndex;
535     }
536 
537     /**
538      * Get the value of the minimum entry.
539      *
540      * @return the value of the minimum entry or {@code NaN} if all
541      * entries are {@code NaN}.
542      */
543     public double getMinValue() {
544         final int minIndex = getMinIndex();
545         return minIndex < 0 ? Double.NaN : getEntry(minIndex);
546     }
547 
548     /**
549      * Get the index of the maximum entry.
550      *
551      * @return the index of the maximum entry or -1 if vector length is 0
552      * or all entries are {@code NaN}
553      */
554     public int getMaxIndex() {
555         int maxIndex    = -1;
556         double maxValue = Double.NEGATIVE_INFINITY;
557         Iterator<Entry> iterator = iterator();
558         while (iterator.hasNext()) {
559             final Entry entry = iterator.next();
560             if (entry.getValue() >= maxValue) {
561                 maxIndex = entry.getIndex();
562                 maxValue = entry.getValue();
563             }
564         }
565         return maxIndex;
566     }
567 
568     /**
569      * Get the value of the maximum entry.
570      *
571      * @return the value of the maximum entry or {@code NaN} if all
572      * entries are {@code NaN}.
573      */
574     public double getMaxValue() {
575         final int maxIndex = getMaxIndex();
576         return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
577     }
578 
579 
580     /**
581      * Multiply each entry by the argument. Returns a new vector.
582      * Does not change instance data.
583      *
584      * @param d Multiplication factor.
585      * @return {@code this} * {@code d}.
586      */
587     public RealVector mapMultiply(double d) {
588         return copy().mapMultiplyToSelf(d);
589     }
590 
591     /**
592      * Multiply each entry.
593      * The instance is changed in-place.
594      *
595      * @param d Multiplication factor.
596      * @return {@code this}.
597      */
598     public RealVector mapMultiplyToSelf(double d){
599         return mapToSelf(FunctionUtils.fix2ndArgument(new Multiply(), d));
600     }
601 
602     /**
603      * Subtract a value from each entry. Returns a new vector.
604      * Does not change instance data.
605      *
606      * @param d Value to be subtracted.
607      * @return {@code this} - {@code d}.
608      */
609     public RealVector mapSubtract(double d) {
610         return copy().mapSubtractToSelf(d);
611     }
612 
613     /**
614      * Subtract a value from each entry.
615      * The instance is changed in-place.
616      *
617      * @param d Value to be subtracted.
618      * @return {@code this}.
619      */
620     public RealVector mapSubtractToSelf(double d){
621         return mapAddToSelf(-d);
622     }
623 
624     /**
625      * Divide each entry by the argument. Returns a new vector.
626      * Does not change instance data.
627      *
628      * @param d Value to divide by.
629      * @return {@code this} / {@code d}.
630      */
631     public RealVector mapDivide(double d) {
632         return copy().mapDivideToSelf(d);
633     }
634 
635     /**
636      * Divide each entry by the argument.
637      * The instance is changed in-place.
638      *
639      * @param d Value to divide by.
640      * @return {@code this}.
641      */
642     public RealVector mapDivideToSelf(double d){
643         return mapToSelf(FunctionUtils.fix2ndArgument(new Divide(), d));
644     }
645 
646     /**
647      * Compute the outer product.
648      *
649      * @param v Vector with which outer product should be computed.
650      * @return the matrix outer product between this instance and {@code v}.
651      */
652     public RealMatrix outerProduct(RealVector v) {
653         final int m = this.getDimension();
654         final int n = v.getDimension();
655         final RealMatrix product;
656         if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
657             product = new OpenMapRealMatrix(m, n);
658         } else {
659             product = new Array2DRowRealMatrix(m, n);
660         }
661         for (int i = 0; i < m; i++) {
662             for (int j = 0; j < n; j++) {
663                 product.setEntry(i, j, this.getEntry(i) * v.getEntry(j));
664             }
665         }
666         return product;
667     }
668 
669     /**
670      * Find the orthogonal projection of this vector onto another vector.
671      *
672      * @param v vector onto which instance must be projected.
673      * @return projection of the instance onto {@code v}.
674      * @throws DimensionMismatchException if {@code v} is not the same size as
675      * {@code this} vector.
676      * @throws MathArithmeticException if {@code this} or {@code v} is the null
677      * vector
678      */
679     public RealVector projection(final RealVector v)
680         throws DimensionMismatchException, MathArithmeticException {
681         final double norm2 = v.dotProduct(v);
682         if (norm2 == 0.0) {
683             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
684         }
685         return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
686     }
687 
688     /**
689      * Set all elements to a single value.
690      *
691      * @param value Single value to set for all elements.
692      */
693     public void set(double value) {
694         Iterator<Entry> it = iterator();
695         while (it.hasNext()) {
696             final Entry e = it.next();
697             e.setValue(value);
698         }
699     }
700 
701     /**
702      * Convert the vector to an array of {@code double}s.
703      * The array is independent from this vector data: the elements
704      * are copied.
705      *
706      * @return an array containing a copy of the vector elements.
707      */
708     public double[] toArray() {
709         int dim = getDimension();
710         double[] values = new double[dim];
711         for (int i = 0; i < dim; i++) {
712             values[i] = getEntry(i);
713         }
714         return values;
715     }
716 
717     /**
718      * Creates a unit vector pointing in the direction of this vector.
719      * The instance is not changed by this method.
720      *
721      * @return a unit vector pointing in direction of this vector.
722      * @throws MathArithmeticException if the norm is zero.
723      */
724     public RealVector unitVector() throws MathArithmeticException {
725         final double norm = getNorm();
726         if (norm == 0) {
727             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
728         }
729         return mapDivide(norm);
730     }
731 
732     /**
733      * Converts this vector into a unit vector.
734      * The instance itself is changed by this method.
735      *
736      * @throws MathArithmeticException if the norm is zero.
737      */
738     public void unitize() throws MathArithmeticException {
739         final double norm = getNorm();
740         if (norm == 0) {
741             throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
742         }
743         mapDivideToSelf(getNorm());
744     }
745 
746     /**
747      * Create a sparse iterator over the vector, which may omit some entries.
748      * Specialized implementations may choose to not iterate over all
749      * dimensions, either because those values are unset, or are equal
750      * to defaultValue(), or are small enough to be ignored for the
751      * purposes of iteration. No guarantees are made about order of iteration.
752      * In dense implementations, this method will often delegate to
753      * {@link #iterator()}.
754      *
755      * <p>Note: derived classes are required to return an {@link Iterator} that
756      * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
757      * returns {@code true}.</p>
758      *
759      * @return a sparse iterator.
760      * @deprecated As of 3.1, this method is deprecated, because its interface
761      * is too confusing (see
762      * <a href="https://issues.apache.org/jira/browse/MATH-875">JIRA MATH-875</a>).
763      * This method will be completely removed in 4.0.
764      */
765     @Deprecated
766     public Iterator<Entry> sparseIterator() {
767         return new SparseEntryIterator();
768     }
769 
770     /**
771      * Generic dense iterator. Iteration is in increasing order
772      * of the vector index.
773      *
774      * <p>Note: derived classes are required to return an {@link Iterator} that
775      * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
776      * returns {@code true}.</p>
777      *
778      * @return a dense iterator.
779      */
780     public Iterator<Entry> iterator() {
781         final int dim = getDimension();
782         return new Iterator<Entry>() {
783 
784             /** Current index. */
785             private int i = 0;
786 
787             /** Current entry. */
788             private Entry e = new Entry();
789 
790             /** {@inheritDoc} */
791             public boolean hasNext() {
792                 return i < dim;
793             }
794 
795             /** {@inheritDoc} */
796             public Entry next() {
797                 if (i < dim) {
798                     e.setIndex(i++);
799                     return e;
800                 } else {
801                     throw new NoSuchElementException();
802                 }
803             }
804 
805             /**
806              * {@inheritDoc}
807              *
808              * @throws MathUnsupportedOperationException in all circumstances.
809              */
810             public void remove() throws MathUnsupportedOperationException {
811                 throw new MathUnsupportedOperationException();
812             }
813         };
814     }
815 
816     /**
817      * Acts as if implemented as:
818      * <pre>
819      *  return copy().mapToSelf(function);
820      * </pre>
821      * Returns a new vector. Does not change instance data.
822      *
823      * @param function Function to apply to each entry.
824      * @return a new vector.
825      */
826     public RealVector map(UnivariateFunction function) {
827         return copy().mapToSelf(function);
828     }
829 
830     /**
831      * Acts as if it is implemented as:
832      * <pre>
833      *  Entry e = null;
834      *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
835      *      e.setValue(function.value(e.getValue()));
836      *  }
837      * </pre>
838      * Entries of this vector are modified in-place by this method.
839      *
840      * @param function Function to apply to each entry.
841      * @return a reference to this vector.
842      */
843     public RealVector mapToSelf(UnivariateFunction function) {
844         Iterator<Entry> it = iterator();
845         while (it.hasNext()) {
846             final Entry e = it.next();
847             e.setValue(function.value(e.getValue()));
848         }
849         return this;
850     }
851 
852     /**
853      * Returns a new vector representing {@code a * this + b * y}, the linear
854      * combination of {@code this} and {@code y}.
855      * Returns a new vector. Does not change instance data.
856      *
857      * @param a Coefficient of {@code this}.
858      * @param b Coefficient of {@code y}.
859      * @param y Vector with which {@code this} is linearly combined.
860      * @return a vector containing {@code a * this[i] + b * y[i]} for all
861      * {@code i}.
862      * @throws DimensionMismatchException if {@code y} is not the same size as
863      * {@code this} vector.
864      */
865     public RealVector combine(double a, double b, RealVector y)
866         throws DimensionMismatchException {
867         return copy().combineToSelf(a, b, y);
868     }
869 
870     /**
871      * Updates {@code this} with the linear combination of {@code this} and
872      * {@code y}.
873      *
874      * @param a Weight of {@code this}.
875      * @param b Weight of {@code y}.
876      * @param y Vector with which {@code this} is linearly combined.
877      * @return {@code this}, with components equal to
878      * {@code a * this[i] + b * y[i]} for all {@code i}.
879      * @throws DimensionMismatchException if {@code y} is not the same size as
880      * {@code this} vector.
881      */
882     public RealVector combineToSelf(double a, double b, RealVector y)
883         throws DimensionMismatchException {
884         checkVectorDimensions(y);
885         for (int i = 0; i < getDimension(); i++) {
886             final double xi = getEntry(i);
887             final double yi = y.getEntry(i);
888             setEntry(i, a * xi + b * yi);
889         }
890         return this;
891     }
892 
893     /**
894      * Visits (but does not alter) all entries of this vector in default order
895      * (increasing index).
896      *
897      * @param visitor the visitor to be used to process the entries of this
898      * vector
899      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
900      * at the end of the walk
901      * @since 3.1
902      */
903     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
904         final int dim = getDimension();
905         visitor.start(dim, 0, dim - 1);
906         for (int i = 0; i < dim; i++) {
907             visitor.visit(i, getEntry(i));
908         }
909         return visitor.end();
910     }
911 
912     /**
913      * Visits (but does not alter) some entries of this vector in default order
914      * (increasing index).
915      *
916      * @param visitor visitor to be used to process the entries of this vector
917      * @param start the index of the first entry to be visited
918      * @param end the index of the last entry to be visited (inclusive)
919      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
920      * at the end of the walk
921      * @throws NumberIsTooSmallException if {@code end < start}.
922      * @throws OutOfRangeException if the indices are not valid.
923      * @since 3.1
924      */
925     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
926                                      final int start, final int end)
927         throws NumberIsTooSmallException, OutOfRangeException {
928         checkIndices(start, end);
929         visitor.start(getDimension(), start, end);
930         for (int i = start; i <= end; i++) {
931             visitor.visit(i, getEntry(i));
932         }
933         return visitor.end();
934     }
935 
936     /**
937      * Visits (but does not alter) all entries of this vector in optimized
938      * order. The order in which the entries are visited is selected so as to
939      * lead to the most efficient implementation; it might depend on the
940      * concrete implementation of this abstract class.
941      *
942      * @param visitor the visitor to be used to process the entries of this
943      * vector
944      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
945      * at the end of the walk
946      * @since 3.1
947      */
948     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
949         return walkInDefaultOrder(visitor);
950     }
951 
952     /**
953      * Visits (but does not alter) some entries of this vector in optimized
954      * order. The order in which the entries are visited is selected so as to
955      * lead to the most efficient implementation; it might depend on the
956      * concrete implementation of this abstract class.
957      *
958      * @param visitor visitor to be used to process the entries of this vector
959      * @param start the index of the first entry to be visited
960      * @param end the index of the last entry to be visited (inclusive)
961      * @return the value returned by {@link RealVectorPreservingVisitor#end()}
962      * at the end of the walk
963      * @throws NumberIsTooSmallException if {@code end < start}.
964      * @throws OutOfRangeException if the indices are not valid.
965      * @since 3.1
966      */
967     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
968                                        final int start, final int end)
969         throws NumberIsTooSmallException, OutOfRangeException {
970         return walkInDefaultOrder(visitor, start, end);
971     }
972 
973     /**
974      * Visits (and possibly alters) all entries of this vector in default order
975      * (increasing index).
976      *
977      * @param visitor the visitor to be used to process and modify the entries
978      * of this vector
979      * @return the value returned by {@link RealVectorChangingVisitor#end()}
980      * at the end of the walk
981      * @since 3.1
982      */
983     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
984         final int dim = getDimension();
985         visitor.start(dim, 0, dim - 1);
986         for (int i = 0; i < dim; i++) {
987             setEntry(i, visitor.visit(i, getEntry(i)));
988         }
989         return visitor.end();
990     }
991 
992     /**
993      * Visits (and possibly alters) some entries of this vector in default order
994      * (increasing index).
995      *
996      * @param visitor visitor to be used to process the entries of this vector
997      * @param start the index of the first entry to be visited
998      * @param end the index of the last entry to be visited (inclusive)
999      * @return the value returned by {@link RealVectorChangingVisitor#end()}
1000      * at the end of the walk
1001      * @throws NumberIsTooSmallException if {@code end < start}.
1002      * @throws OutOfRangeException if the indices are not valid.
1003      * @since 3.1
1004      */
1005     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
1006                               final int start, final int end)
1007         throws NumberIsTooSmallException, OutOfRangeException {
1008         checkIndices(start, end);
1009         visitor.start(getDimension(), start, end);
1010         for (int i = start; i <= end; i++) {
1011             setEntry(i, visitor.visit(i, getEntry(i)));
1012         }
1013         return visitor.end();
1014     }
1015 
1016     /**
1017      * Visits (and possibly alters) all entries of this vector in optimized
1018      * order. The order in which the entries are visited is selected so as to
1019      * lead to the most efficient implementation; it might depend on the
1020      * concrete implementation of this abstract class.
1021      *
1022      * @param visitor the visitor to be used to process the entries of this
1023      * vector
1024      * @return the value returned by {@link RealVectorChangingVisitor#end()}
1025      * at the end of the walk
1026      * @since 3.1
1027      */
1028     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
1029         return walkInDefaultOrder(visitor);
1030     }
1031 
1032     /**
1033      * Visits (and possibly change) some entries of this vector in optimized
1034      * order. The order in which the entries are visited is selected so as to
1035      * lead to the most efficient implementation; it might depend on the
1036      * concrete implementation of this abstract class.
1037      *
1038      * @param visitor visitor to be used to process the entries of this vector
1039      * @param start the index of the first entry to be visited
1040      * @param end the index of the last entry to be visited (inclusive)
1041      * @return the value returned by {@link RealVectorChangingVisitor#end()}
1042      * at the end of the walk
1043      * @throws NumberIsTooSmallException if {@code end < start}.
1044      * @throws OutOfRangeException if the indices are not valid.
1045      * @since 3.1
1046      */
1047     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
1048                                        final int start, final int end)
1049         throws NumberIsTooSmallException, OutOfRangeException {
1050         return walkInDefaultOrder(visitor, start, end);
1051     }
1052 
1053     /** An entry in the vector. */
1054     protected class Entry {
1055         /** Index of this entry. */
1056         private int index;
1057 
1058         /** Simple constructor. */
1059         public Entry() {
1060             setIndex(0);
1061         }
1062 
1063         /**
1064          * Get the value of the entry.
1065          *
1066          * @return the value of the entry.
1067          */
1068         public double getValue() {
1069             return getEntry(getIndex());
1070         }
1071 
1072         /**
1073          * Set the value of the entry.
1074          *
1075          * @param value New value for the entry.
1076          */
1077         public void setValue(double value) {
1078             setEntry(getIndex(), value);
1079         }
1080 
1081         /**
1082          * Get the index of the entry.
1083          *
1084          * @return the index of the entry.
1085          */
1086         public int getIndex() {
1087             return index;
1088         }
1089 
1090         /**
1091          * Set the index of the entry.
1092          *
1093          * @param index New index for the entry.
1094          */
1095         public void setIndex(int index) {
1096             this.index = index;
1097         }
1098     }
1099 
1100     /**
1101      * <p>
1102      * Test for the equality of two real vectors. If all coordinates of two real
1103      * vectors are exactly the same, and none are {@code NaN}, the two real
1104      * vectors are considered to be equal. {@code NaN} coordinates are
1105      * considered to affect globally the vector and be equals to each other -
1106      * i.e, if either (or all) coordinates of the real vector are equal to
1107      * {@code NaN}, the real vector is equal to a vector with all {@code NaN}
1108      * coordinates.
1109      * </p>
1110      * <p>
1111      * This method <em>must</em> be overriden by concrete subclasses of
1112      * {@link RealVector} (the current implementation throws an exception).
1113      * </p>
1114      *
1115      * @param other Object to test for equality.
1116      * @return {@code true} if two vector objects are equal, {@code false} if
1117      * {@code other} is null, not an instance of {@code RealVector}, or
1118      * not equal to this {@code RealVector} instance.
1119      * @throws MathUnsupportedOperationException if this method is not
1120      * overridden.
1121      */
1122     @Override
1123     public boolean equals(Object other)
1124         throws MathUnsupportedOperationException {
1125         throw new MathUnsupportedOperationException();
1126     }
1127 
1128     /**
1129      * {@inheritDoc}. This method <em>must</em> be overriden by concrete
1130      * subclasses of {@link RealVector} (current implementation throws an
1131      * exception).
1132      *
1133      * @throws MathUnsupportedOperationException if this method is not
1134      * overridden.
1135      */
1136     @Override
1137     public int hashCode() throws MathUnsupportedOperationException {
1138         throw new MathUnsupportedOperationException();
1139     }
1140 
1141     /**
1142      * This class should rarely be used, but is here to provide
1143      * a default implementation of sparseIterator(), which is implemented
1144      * by walking over the entries, skipping those whose values are the default one.
1145      *
1146      * Concrete subclasses which are SparseVector implementations should
1147      * make their own sparse iterator, rather than using this one.
1148      *
1149      * This implementation might be useful for ArrayRealVector, when expensive
1150      * operations which preserve the default value are to be done on the entries,
1151      * and the fraction of non-default values is small (i.e. someone took a
1152      * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
1153      *
1154      * @deprecated As of 3.1, this class is deprecated, see
1155      * <a href="https://issues.apache.org/jira/browse/MATH-875">JIRA MATH-875</a>.
1156      * This class will be completely removed in 4.0.
1157 
1158      */
1159     @Deprecated
1160     protected class SparseEntryIterator implements Iterator<Entry> {
1161         /** Dimension of the vector. */
1162         private final int dim;
1163         /** Last entry returned by {@link #next()}. */
1164         private Entry current;
1165         /** Next entry for {@link #next()} to return. */
1166         private Entry next;
1167 
1168         /** Simple constructor. */
1169         protected SparseEntryIterator() {
1170             dim = getDimension();
1171             current = new Entry();
1172             next = new Entry();
1173             if (next.getValue() == 0) {
1174                 advance(next);
1175             }
1176         }
1177 
1178         /**
1179          * Advance an entry up to the next nonzero one.
1180          *
1181          * @param e entry to advance.
1182          */
1183         protected void advance(Entry e) {
1184             if (e == null) {
1185                 return;
1186             }
1187             do {
1188                 e.setIndex(e.getIndex() + 1);
1189             } while (e.getIndex() < dim && e.getValue() == 0);
1190             if (e.getIndex() >= dim) {
1191                 e.setIndex(-1);
1192             }
1193         }
1194 
1195         /** {@inheritDoc} */
1196         public boolean hasNext() {
1197             return next.getIndex() >= 0;
1198         }
1199 
1200         /** {@inheritDoc} */
1201         public Entry next() {
1202             int index = next.getIndex();
1203             if (index < 0) {
1204                 throw new NoSuchElementException();
1205             }
1206             current.setIndex(index);
1207             advance(next);
1208             return current;
1209         }
1210 
1211         /**
1212          * {@inheritDoc}
1213          *
1214          * @throws MathUnsupportedOperationException in all circumstances.
1215          */
1216         public void remove() throws MathUnsupportedOperationException {
1217             throw new MathUnsupportedOperationException();
1218         }
1219     }
1220 
1221     /**
1222      * Returns an unmodifiable view of the specified vector.
1223      * The returned vector has read-only access. An attempt to modify it will
1224      * result in a {@link MathUnsupportedOperationException}. However, the
1225      * returned vector is <em>not</em> immutable, since any modification of
1226      * {@code v} will also change the returned view.
1227      * For example, in the following piece of code
1228      * <pre>
1229      *     RealVector v = new ArrayRealVector(2);
1230      *     RealVector w = RealVector.unmodifiableRealVector(v);
1231      *     v.setEntry(0, 1.2);
1232      *     v.setEntry(1, -3.4);
1233      * </pre>
1234      * the changes will be seen in the {@code w} view of {@code v}.
1235      *
1236      * @param v Vector for which an unmodifiable view is to be returned.
1237      * @return an unmodifiable view of {@code v}.
1238      */
1239     public static RealVector unmodifiableRealVector(final RealVector v) {
1240         /**
1241          * This anonymous class is an implementation of {@link RealVector}
1242          * with read-only access.
1243          * It wraps any {@link RealVector}, and exposes all methods which
1244          * do not modify it. Invoking methods which should normally result
1245          * in the modification of the calling {@link RealVector} results in
1246          * a {@link MathUnsupportedOperationException}. It should be noted
1247          * that {@link UnmodifiableVector} is <em>not</em> immutable.
1248          */
1249         return new RealVector() {
1250             /**
1251              * {@inheritDoc}
1252              *
1253              * @throws MathUnsupportedOperationException in all circumstances.
1254              */
1255             @Override
1256             public RealVector mapToSelf(UnivariateFunction function)
1257                 throws MathUnsupportedOperationException {
1258                 throw new MathUnsupportedOperationException();
1259             }
1260 
1261             /** {@inheritDoc} */
1262             @Override
1263             public RealVector map(UnivariateFunction function) {
1264                 return v.map(function);
1265             }
1266 
1267             /** {@inheritDoc} */
1268             @Override
1269             public Iterator<Entry> iterator() {
1270                 final Iterator<Entry> i = v.iterator();
1271                 return new Iterator<Entry>() {
1272                     /** The current entry. */
1273                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1274 
1275                     /** {@inheritDoc} */
1276                     public boolean hasNext() {
1277                         return i.hasNext();
1278                     }
1279 
1280                     /** {@inheritDoc} */
1281                     public Entry next() {
1282                         e.setIndex(i.next().getIndex());
1283                         return e;
1284                     }
1285 
1286                     /**
1287                      * {@inheritDoc}
1288                      *
1289                      * @throws MathUnsupportedOperationException in all
1290                      * circumstances.
1291                      */
1292                     public void remove() throws MathUnsupportedOperationException {
1293                         throw new MathUnsupportedOperationException();
1294                     }
1295                 };
1296             }
1297 
1298             /** {@inheritDoc} */
1299             @Override
1300             public Iterator<Entry> sparseIterator() {
1301                 final Iterator<Entry> i = v.sparseIterator();
1302 
1303                 return new Iterator<Entry>() {
1304                     /** The current entry. */
1305                     private final UnmodifiableEntry e = new UnmodifiableEntry();
1306 
1307                     /** {@inheritDoc} */
1308                     public boolean hasNext() {
1309                         return i.hasNext();
1310                     }
1311 
1312                     /** {@inheritDoc} */
1313                     public Entry next() {
1314                         e.setIndex(i.next().getIndex());
1315                         return e;
1316                     }
1317 
1318                     /**
1319                      * {@inheritDoc}
1320                      *
1321                      * @throws MathUnsupportedOperationException in all
1322                      * circumstances.
1323                      */
1324                     public void remove()
1325                         throws MathUnsupportedOperationException {
1326                         throw new MathUnsupportedOperationException();
1327                     }
1328                 };
1329             }
1330 
1331             /** {@inheritDoc} */
1332             @Override
1333             public RealVector copy() {
1334                 return v.copy();
1335             }
1336 
1337             /** {@inheritDoc} */
1338             @Override
1339             public RealVector add(RealVector w)
1340                 throws DimensionMismatchException {
1341                 return v.add(w);
1342             }
1343 
1344             /** {@inheritDoc} */
1345             @Override
1346             public RealVector subtract(RealVector w)
1347                 throws DimensionMismatchException {
1348                 return v.subtract(w);
1349             }
1350 
1351             /** {@inheritDoc} */
1352             @Override
1353             public RealVector mapAdd(double d) {
1354                 return v.mapAdd(d);
1355             }
1356 
1357             /**
1358              * {@inheritDoc}
1359              *
1360              * @throws MathUnsupportedOperationException in all
1361              * circumstances.
1362              */
1363             @Override
1364             public RealVector mapAddToSelf(double d)
1365                 throws MathUnsupportedOperationException {
1366                 throw new MathUnsupportedOperationException();
1367             }
1368 
1369             /** {@inheritDoc} */
1370             @Override
1371             public RealVector mapSubtract(double d) {
1372                 return v.mapSubtract(d);
1373             }
1374 
1375             /**
1376              * {@inheritDoc}
1377              *
1378              * @throws MathUnsupportedOperationException in all
1379              * circumstances.
1380              */
1381             @Override
1382             public RealVector mapSubtractToSelf(double d)
1383                 throws MathUnsupportedOperationException {
1384                 throw new MathUnsupportedOperationException();
1385             }
1386 
1387             /** {@inheritDoc} */
1388             @Override
1389             public RealVector mapMultiply(double d) {
1390                 return v.mapMultiply(d);
1391             }
1392 
1393             /**
1394              * {@inheritDoc}
1395              *
1396              * @throws MathUnsupportedOperationException in all
1397              * circumstances.
1398              */
1399             @Override
1400             public RealVector mapMultiplyToSelf(double d)
1401                 throws MathUnsupportedOperationException {
1402                 throw new MathUnsupportedOperationException();
1403             }
1404 
1405             /** {@inheritDoc} */
1406             @Override
1407             public RealVector mapDivide(double d) {
1408                 return v.mapDivide(d);
1409             }
1410 
1411             /**
1412              * {@inheritDoc}
1413              *
1414              * @throws MathUnsupportedOperationException in all
1415              * circumstances.
1416              */
1417             @Override
1418             public RealVector mapDivideToSelf(double d)
1419                 throws MathUnsupportedOperationException {
1420                 throw new MathUnsupportedOperationException();
1421             }
1422 
1423             /** {@inheritDoc} */
1424             @Override
1425             public RealVector ebeMultiply(RealVector w)
1426                 throws DimensionMismatchException {
1427                 return v.ebeMultiply(w);
1428             }
1429 
1430             /** {@inheritDoc} */
1431             @Override
1432             public RealVector ebeDivide(RealVector w)
1433                 throws DimensionMismatchException {
1434                 return v.ebeDivide(w);
1435             }
1436 
1437             /** {@inheritDoc} */
1438             @Override
1439             public double dotProduct(RealVector w)
1440                 throws DimensionMismatchException {
1441                 return v.dotProduct(w);
1442             }
1443 
1444             /** {@inheritDoc} */
1445             @Override
1446             public double cosine(RealVector w)
1447                 throws DimensionMismatchException, MathArithmeticException {
1448                 return v.cosine(w);
1449             }
1450 
1451             /** {@inheritDoc} */
1452             @Override
1453             public double getNorm() {
1454                 return v.getNorm();
1455             }
1456 
1457             /** {@inheritDoc} */
1458             @Override
1459             public double getL1Norm() {
1460                 return v.getL1Norm();
1461             }
1462 
1463             /** {@inheritDoc} */
1464             @Override
1465             public double getLInfNorm() {
1466                 return v.getLInfNorm();
1467             }
1468 
1469             /** {@inheritDoc} */
1470             @Override
1471             public double getDistance(RealVector w)
1472                 throws DimensionMismatchException {
1473                 return v.getDistance(w);
1474             }
1475 
1476             /** {@inheritDoc} */
1477             @Override
1478             public double getL1Distance(RealVector w)
1479                 throws DimensionMismatchException {
1480                 return v.getL1Distance(w);
1481             }
1482 
1483             /** {@inheritDoc} */
1484             @Override
1485             public double getLInfDistance(RealVector w)
1486                 throws DimensionMismatchException {
1487                 return v.getLInfDistance(w);
1488             }
1489 
1490             /** {@inheritDoc} */
1491             @Override
1492             public RealVector unitVector() throws MathArithmeticException {
1493                 return v.unitVector();
1494             }
1495 
1496             /**
1497              * {@inheritDoc}
1498              *
1499              * @throws MathUnsupportedOperationException in all
1500              * circumstances.
1501              */
1502             @Override
1503             public void unitize() throws MathUnsupportedOperationException {
1504                 throw new MathUnsupportedOperationException();
1505             }
1506 
1507             /** {@inheritDoc} */
1508             @Override
1509             public RealMatrix outerProduct(RealVector w) {
1510                 return v.outerProduct(w);
1511             }
1512 
1513             /** {@inheritDoc} */
1514             @Override
1515             public double getEntry(int index) throws OutOfRangeException {
1516                 return v.getEntry(index);
1517             }
1518 
1519             /**
1520              * {@inheritDoc}
1521              *
1522              * @throws MathUnsupportedOperationException in all
1523              * circumstances.
1524              */
1525             @Override
1526             public void setEntry(int index, double value)
1527                 throws MathUnsupportedOperationException {
1528                 throw new MathUnsupportedOperationException();
1529             }
1530 
1531             /**
1532              * {@inheritDoc}
1533              *
1534              * @throws MathUnsupportedOperationException in all
1535              * circumstances.
1536              */
1537             @Override
1538             public void addToEntry(int index, double value)
1539                 throws MathUnsupportedOperationException {
1540                 throw new MathUnsupportedOperationException();
1541             }
1542 
1543             /** {@inheritDoc} */
1544             @Override
1545             public int getDimension() {
1546                 return v.getDimension();
1547             }
1548 
1549             /** {@inheritDoc} */
1550             @Override
1551             public RealVector append(RealVector w) {
1552                 return v.append(w);
1553             }
1554 
1555             /** {@inheritDoc} */
1556             @Override
1557             public RealVector append(double d) {
1558                 return v.append(d);
1559             }
1560 
1561             /** {@inheritDoc} */
1562             @Override
1563             public RealVector getSubVector(int index, int n)
1564                 throws OutOfRangeException, NotPositiveException {
1565                 return v.getSubVector(index, n);
1566             }
1567 
1568             /**
1569              * {@inheritDoc}
1570              *
1571              * @throws MathUnsupportedOperationException in all
1572              * circumstances.
1573              */
1574             @Override
1575             public void setSubVector(int index, RealVector w)
1576                 throws MathUnsupportedOperationException {
1577                 throw new MathUnsupportedOperationException();
1578             }
1579 
1580             /**
1581              * {@inheritDoc}
1582              *
1583              * @throws MathUnsupportedOperationException in all
1584              * circumstances.
1585              */
1586             @Override
1587             public void set(double value)
1588                 throws MathUnsupportedOperationException {
1589                 throw new MathUnsupportedOperationException();
1590             }
1591 
1592             /** {@inheritDoc} */
1593             @Override
1594             public double[] toArray() {
1595                 return v.toArray();
1596             }
1597 
1598             /** {@inheritDoc} */
1599             @Override
1600             public boolean isNaN() {
1601                 return v.isNaN();
1602             }
1603 
1604             /** {@inheritDoc} */
1605             @Override
1606             public boolean isInfinite() {
1607                 return v.isInfinite();
1608             }
1609 
1610             /** {@inheritDoc} */
1611             @Override
1612             public RealVector combine(double a, double b, RealVector y)
1613                 throws DimensionMismatchException {
1614                 return v.combine(a, b, y);
1615             }
1616 
1617             /**
1618              * {@inheritDoc}
1619              *
1620              * @throws MathUnsupportedOperationException in all
1621              * circumstances.
1622              */
1623             @Override
1624             public RealVector combineToSelf(double a, double b, RealVector y)
1625                 throws MathUnsupportedOperationException {
1626                 throw new MathUnsupportedOperationException();
1627             }
1628 
1629             /** An entry in the vector. */
1630             class UnmodifiableEntry extends Entry {
1631                 /** {@inheritDoc} */
1632                 @Override
1633                 public double getValue() {
1634                     return v.getEntry(getIndex());
1635                 }
1636 
1637                 /**
1638                  * {@inheritDoc}
1639                  *
1640                  * @throws MathUnsupportedOperationException in all
1641                  * circumstances.
1642                  */
1643                 @Override
1644                 public void setValue(double value)
1645                     throws MathUnsupportedOperationException {
1646                     throw new MathUnsupportedOperationException();
1647                 }
1648             }
1649         };
1650     }
1651 }