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