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