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