001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math3.linear;
019    
020    import java.util.Iterator;
021    import java.util.NoSuchElementException;
022    
023    import org.apache.commons.math3.exception.MathUnsupportedOperationException;
024    import org.apache.commons.math3.exception.DimensionMismatchException;
025    import org.apache.commons.math3.exception.NotPositiveException;
026    import org.apache.commons.math3.exception.NumberIsTooSmallException;
027    import org.apache.commons.math3.exception.OutOfRangeException;
028    import org.apache.commons.math3.exception.MathArithmeticException;
029    import org.apache.commons.math3.analysis.FunctionUtils;
030    import org.apache.commons.math3.analysis.function.Add;
031    import org.apache.commons.math3.analysis.function.Multiply;
032    import org.apache.commons.math3.analysis.function.Divide;
033    import org.apache.commons.math3.analysis.UnivariateFunction;
034    import org.apache.commons.math3.exception.util.LocalizedFormats;
035    import org.apache.commons.math3.util.FastMath;
036    
037    /**
038     * Class defining a real-valued vector with basic algebraic operations.
039     * <p>
040     * vector element indexing is 0-based -- e.g., {@code getEntry(0)}
041     * returns the first element of the vector.
042     * </p>
043     * <p>
044     * The {@code code map} and {@code mapToSelf} methods operate
045     * on vectors element-wise, i.e. they perform the same operation (adding a scalar,
046     * applying a function ...) on each element in turn. The {@code map}
047     * versions create a new vector to hold the result and do not change the instance.
048     * The {@code mapToSelf} version uses the instance itself to store the
049     * results, so the instance is changed by this method. In all cases, the result
050     * vector is returned by the methods, allowing the <i>fluent API</i>
051     * style, like this:
052     * </p>
053     * <pre>
054     *   RealVector result = v.mapAddToSelf(3.4).mapToSelf(new Tan()).mapToSelf(new Power(2.3));
055     * </pre>
056     *
057     * @version $Id: RealVector.java 1422313 2012-12-15 18:53:41Z psteitz $
058     * @since 2.1
059     */
060    public abstract class RealVector {
061        /**
062         * Returns the size of the vector.
063         *
064         * @return the size of this vector.
065         */
066        public abstract int getDimension();
067    
068        /**
069         * Return the entry at the specified index.
070         *
071         * @param index Index location of entry to be fetched.
072         * @return the vector entry at {@code index}.
073         * @throws OutOfRangeException if the index is not valid.
074         * @see #setEntry(int, double)
075         */
076        public abstract double getEntry(int index) throws OutOfRangeException;
077    
078        /**
079         * Set a single element.
080         *
081         * @param index element index.
082         * @param value new value for the element.
083         * @throws OutOfRangeException if the index is not valid.
084         * @see #getEntry(int)
085         */
086        public abstract void setEntry(int index, double value)
087            throws OutOfRangeException;
088    
089        /**
090         * Change an entry at the specified index.
091         *
092         * @param index Index location of entry to be set.
093         * @param increment Value to add to the vector entry.
094         * @throws OutOfRangeException if the index is not valid.
095         * @since 3.0
096         */
097        public void addToEntry(int index, double increment)
098            throws OutOfRangeException {
099            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    }