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.math4.legacy.linear;
019
020import java.util.Iterator;
021import java.util.NoSuchElementException;
022
023import org.apache.commons.math4.legacy.analysis.FunctionUtils;
024import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
025import org.apache.commons.math4.legacy.analysis.function.Add;
026import org.apache.commons.math4.legacy.analysis.function.Divide;
027import org.apache.commons.math4.legacy.analysis.function.Multiply;
028import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
029import org.apache.commons.math4.legacy.exception.MathArithmeticException;
030import org.apache.commons.math4.legacy.exception.MathUnsupportedOperationException;
031import org.apache.commons.math4.legacy.exception.NotPositiveException;
032import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
033import org.apache.commons.math4.legacy.exception.OutOfRangeException;
034import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
035import org.apache.commons.math4.core.jdkmath.JdkMath;
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 JdkMath.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 JdkMath.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 += JdkMath.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 = JdkMath.max(norm, JdkMath.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 += JdkMath.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 = JdkMath.max(JdkMath.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;
757
758            /** Current entry. */
759            private Entry e = new Entry();
760
761            /** {@inheritDoc} */
762            @Override
763            public boolean hasNext() {
764                return i < dim;
765            }
766
767            /** {@inheritDoc} */
768            @Override
769            public Entry next() {
770                if (i < dim) {
771                    e.setIndex(i++);
772                    return e;
773                } else {
774                    throw new NoSuchElementException();
775                }
776            }
777
778            /**
779             * {@inheritDoc}
780             *
781             * @throws MathUnsupportedOperationException in all circumstances.
782             */
783            @Override
784            public void remove() throws MathUnsupportedOperationException {
785                throw new MathUnsupportedOperationException();
786            }
787        };
788    }
789
790    /**
791     * Acts as if implemented as:
792     * <pre>
793     *  return copy().mapToSelf(function);
794     * </pre>
795     * Returns a new vector. Does not change instance data.
796     *
797     * @param function Function to apply to each entry.
798     * @return a new vector.
799     */
800    public RealVector map(UnivariateFunction function) {
801        return copy().mapToSelf(function);
802    }
803
804    /**
805     * Acts as if it is implemented as:
806     * {@code
807     *  Entry e = null;
808     *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
809     *      e.setValue(function.value(e.getValue()));
810     *  }
811     * }
812     * Entries of this vector are modified in-place by this method.
813     *
814     * @param function Function to apply to each entry.
815     * @return a reference to this vector.
816     */
817    public RealVector mapToSelf(UnivariateFunction function) {
818        Iterator<Entry> it = iterator();
819        while (it.hasNext()) {
820            final Entry e = it.next();
821            e.setValue(function.value(e.getValue()));
822        }
823        return this;
824    }
825
826    /**
827     * Returns a new vector representing {@code a * this + b * y}, the linear
828     * combination of {@code this} and {@code y}.
829     * Returns a new vector. Does not change instance data.
830     *
831     * @param a Coefficient of {@code this}.
832     * @param b Coefficient of {@code y}.
833     * @param y Vector with which {@code this} is linearly combined.
834     * @return a vector containing {@code a * this[i] + b * y[i]} for all
835     * {@code i}.
836     * @throws DimensionMismatchException if {@code y} is not the same size as
837     * {@code this} vector.
838     */
839    public RealVector combine(double a, double b, RealVector y)
840        throws DimensionMismatchException {
841        return copy().combineToSelf(a, b, y);
842    }
843
844    /**
845     * Updates {@code this} with the linear combination of {@code this} and
846     * {@code y}.
847     *
848     * @param a Weight of {@code this}.
849     * @param b Weight of {@code y}.
850     * @param y Vector with which {@code this} is linearly combined.
851     * @return {@code this}, with components equal to
852     * {@code a * this[i] + b * y[i]} for all {@code i}.
853     * @throws DimensionMismatchException if {@code y} is not the same size as
854     * {@code this} vector.
855     */
856    public RealVector combineToSelf(double a, double b, RealVector y)
857        throws DimensionMismatchException {
858        checkVectorDimensions(y);
859        for (int i = 0; i < getDimension(); i++) {
860            final double xi = getEntry(i);
861            final double yi = y.getEntry(i);
862            setEntry(i, a * xi + b * yi);
863        }
864        return this;
865    }
866
867    /**
868     * Visits (but does not alter) all entries of this vector in default order
869     * (increasing index).
870     *
871     * @param visitor the visitor to be used to process the entries of this
872     * vector
873     * @return the value returned by {@link RealVectorPreservingVisitor#end()}
874     * at the end of the walk
875     * @since 3.1
876     */
877    public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
878        final int dim = getDimension();
879        visitor.start(dim, 0, dim - 1);
880        for (int i = 0; i < dim; i++) {
881            visitor.visit(i, getEntry(i));
882        }
883        return visitor.end();
884    }
885
886    /**
887     * Visits (but does not alter) some entries of this vector in default order
888     * (increasing index).
889     *
890     * @param visitor visitor to be used to process the entries of this vector
891     * @param start the index of the first entry to be visited
892     * @param end the index of the last entry to be visited (inclusive)
893     * @return the value returned by {@link RealVectorPreservingVisitor#end()}
894     * at the end of the walk
895     * @throws NumberIsTooSmallException if {@code end < start}.
896     * @throws OutOfRangeException if the indices are not valid.
897     * @since 3.1
898     */
899    public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
900                                     final int start, final int end)
901        throws NumberIsTooSmallException, OutOfRangeException {
902        checkIndices(start, end);
903        visitor.start(getDimension(), start, end);
904        for (int i = start; i <= end; i++) {
905            visitor.visit(i, getEntry(i));
906        }
907        return visitor.end();
908    }
909
910    /**
911     * Visits (but does not alter) all entries of this vector in optimized
912     * order. The order in which the entries are visited is selected so as to
913     * lead to the most efficient implementation; it might depend on the
914     * concrete implementation of this abstract class.
915     *
916     * @param visitor the visitor to be used to process the entries of this
917     * vector
918     * @return the value returned by {@link RealVectorPreservingVisitor#end()}
919     * at the end of the walk
920     * @since 3.1
921     */
922    public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
923        return walkInDefaultOrder(visitor);
924    }
925
926    /**
927     * Visits (but does not alter) some entries of this vector in optimized
928     * order. The order in which the entries are visited is selected so as to
929     * lead to the most efficient implementation; it might depend on the
930     * concrete implementation of this abstract class.
931     *
932     * @param visitor visitor to be used to process the entries of this vector
933     * @param start the index of the first entry to be visited
934     * @param end the index of the last entry to be visited (inclusive)
935     * @return the value returned by {@link RealVectorPreservingVisitor#end()}
936     * at the end of the walk
937     * @throws NumberIsTooSmallException if {@code end < start}.
938     * @throws OutOfRangeException if the indices are not valid.
939     * @since 3.1
940     */
941    public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
942                                       final int start, final int end)
943        throws NumberIsTooSmallException, OutOfRangeException {
944        return walkInDefaultOrder(visitor, start, end);
945    }
946
947    /**
948     * Visits (and possibly alters) all entries of this vector in default order
949     * (increasing index).
950     *
951     * @param visitor the visitor to be used to process and modify the entries
952     * of this vector
953     * @return the value returned by {@link RealVectorChangingVisitor#end()}
954     * at the end of the walk
955     * @since 3.1
956     */
957    public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
958        final int dim = getDimension();
959        visitor.start(dim, 0, dim - 1);
960        for (int i = 0; i < dim; i++) {
961            setEntry(i, visitor.visit(i, getEntry(i)));
962        }
963        return visitor.end();
964    }
965
966    /**
967     * Visits (and possibly alters) some entries of this vector in default order
968     * (increasing index).
969     *
970     * @param visitor visitor to be used to process the entries of this vector
971     * @param start the index of the first entry to be visited
972     * @param end the index of the last entry to be visited (inclusive)
973     * @return the value returned by {@link RealVectorChangingVisitor#end()}
974     * at the end of the walk
975     * @throws NumberIsTooSmallException if {@code end < start}.
976     * @throws OutOfRangeException if the indices are not valid.
977     * @since 3.1
978     */
979    public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
980                              final int start, final int end)
981        throws NumberIsTooSmallException, OutOfRangeException {
982        checkIndices(start, end);
983        visitor.start(getDimension(), start, end);
984        for (int i = start; i <= end; i++) {
985            setEntry(i, visitor.visit(i, getEntry(i)));
986        }
987        return visitor.end();
988    }
989
990    /**
991     * Visits (and possibly alters) all entries of this vector in optimized
992     * order. The order in which the entries are visited is selected so as to
993     * lead to the most efficient implementation; it might depend on the
994     * concrete implementation of this abstract class.
995     *
996     * @param visitor the visitor to be used to process the entries of this
997     * vector
998     * @return the value returned by {@link RealVectorChangingVisitor#end()}
999     * at the end of the walk
1000     * @since 3.1
1001     */
1002    public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
1003        return walkInDefaultOrder(visitor);
1004    }
1005
1006    /**
1007     * Visits (and possibly change) some entries of this vector in optimized
1008     * order. The order in which the entries are visited is selected so as to
1009     * lead to the most efficient implementation; it might depend on the
1010     * concrete implementation of this abstract class.
1011     *
1012     * @param visitor visitor to be used to process the entries of this vector
1013     * @param start the index of the first entry to be visited
1014     * @param end the index of the last entry to be visited (inclusive)
1015     * @return the value returned by {@link RealVectorChangingVisitor#end()}
1016     * at the end of the walk
1017     * @throws NumberIsTooSmallException if {@code end < start}.
1018     * @throws OutOfRangeException if the indices are not valid.
1019     * @since 3.1
1020     */
1021    public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
1022                                       final int start, final int end)
1023        throws NumberIsTooSmallException, OutOfRangeException {
1024        return walkInDefaultOrder(visitor, start, end);
1025    }
1026
1027    /** An entry in the vector. */
1028    protected class Entry {
1029        /** Index of this entry. */
1030        private int index;
1031
1032        /** Simple constructor. */
1033        public Entry() {
1034            setIndex(0);
1035        }
1036
1037        /**
1038         * Get the value of the entry.
1039         *
1040         * @return the value of the entry.
1041         */
1042        public double getValue() {
1043            return getEntry(getIndex());
1044        }
1045
1046        /**
1047         * Set the value of the entry.
1048         *
1049         * @param value New value for the entry.
1050         */
1051        public void setValue(double value) {
1052            setEntry(getIndex(), value);
1053        }
1054
1055        /**
1056         * Get the index of the entry.
1057         *
1058         * @return the index of the entry.
1059         */
1060        public int getIndex() {
1061            return index;
1062        }
1063
1064        /**
1065         * Set the index of the entry.
1066         *
1067         * @param index New index for the entry.
1068         */
1069        public void setIndex(int index) {
1070            this.index = index;
1071        }
1072    }
1073
1074    /**
1075     * <p>
1076     * Test for the equality of two real vectors. If all coordinates of two real
1077     * vectors are exactly the same, and none are {@code NaN}, the two real
1078     * vectors are considered to be equal. {@code NaN} coordinates are
1079     * considered to affect globally the vector and be equals to each other -
1080     * i.e, if either (or all) coordinates of the real vector are equal to
1081     * {@code NaN}, the real vector is equal to a vector with all {@code NaN}
1082     * coordinates.
1083     * </p>
1084     * <p>
1085     * This method <em>must</em> be overridden by concrete subclasses of
1086     * {@link RealVector} (the current implementation throws an exception).
1087     * </p>
1088     *
1089     * @param other Object to test for equality.
1090     * @return {@code true} if two vector objects are equal, {@code false} if
1091     * {@code other} is null, not an instance of {@code RealVector}, or
1092     * not equal to this {@code RealVector} instance.
1093     * @throws MathUnsupportedOperationException if this method is not
1094     * overridden.
1095     */
1096    @Override
1097    public boolean equals(Object other)
1098        throws MathUnsupportedOperationException {
1099        throw new MathUnsupportedOperationException();
1100    }
1101
1102    /**
1103     * {@inheritDoc}. This method <em>must</em> be overridden by concrete
1104     * subclasses of {@link RealVector} (current implementation throws an
1105     * exception).
1106     *
1107     * @throws MathUnsupportedOperationException if this method is not
1108     * overridden.
1109     */
1110    @Override
1111    public int hashCode() throws MathUnsupportedOperationException {
1112        throw new MathUnsupportedOperationException();
1113    }
1114
1115    /**
1116     * This class should rarely be used, but is here to provide
1117     * a default implementation of sparseIterator(), which is implemented
1118     * by walking over the entries, skipping those that are zero.
1119     *
1120     * Concrete subclasses which are SparseVector implementations should
1121     * make their own sparse iterator, rather than using this one.
1122     *
1123     * This implementation might be useful for ArrayRealVector, when expensive
1124     * operations which preserve the default value are to be done on the entries,
1125     * and the fraction of non-default values is small (i.e. someone took a
1126     * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
1127
1128     */
1129    protected class SparseEntryIterator implements Iterator<Entry> {
1130        /** Dimension of the vector. */
1131        private final int dim;
1132        /** Last entry returned by {@link #next()}. */
1133        private Entry current;
1134        /** Next entry for {@link #next()} to return. */
1135        private Entry next;
1136
1137        /** Simple constructor. */
1138        protected SparseEntryIterator() {
1139            dim = getDimension();
1140            current = new Entry();
1141            next = new Entry();
1142            if (next.getValue() == 0) {
1143                advance(next);
1144            }
1145        }
1146
1147        /**
1148         * Advance an entry up to the next nonzero one.
1149         *
1150         * @param e entry to advance.
1151         */
1152        protected void advance(Entry e) {
1153            if (e == null) {
1154                return;
1155            }
1156            do {
1157                e.setIndex(e.getIndex() + 1);
1158            } while (e.getIndex() < dim && e.getValue() == 0);
1159            if (e.getIndex() >= dim) {
1160                e.setIndex(-1);
1161            }
1162        }
1163
1164        /** {@inheritDoc} */
1165        @Override
1166        public boolean hasNext() {
1167            return next.getIndex() >= 0;
1168        }
1169
1170        /** {@inheritDoc} */
1171        @Override
1172        public Entry next() {
1173            int index = next.getIndex();
1174            if (index < 0) {
1175                throw new NoSuchElementException();
1176            }
1177            current.setIndex(index);
1178            advance(next);
1179            return current;
1180        }
1181
1182        /**
1183         * {@inheritDoc}
1184         *
1185         * @throws MathUnsupportedOperationException in all circumstances.
1186         */
1187        @Override
1188        public void remove() throws MathUnsupportedOperationException {
1189            throw new MathUnsupportedOperationException();
1190        }
1191    }
1192
1193    /**
1194     * Returns an unmodifiable view of the specified vector.
1195     * The returned vector has read-only access. An attempt to modify it will
1196     * result in a {@link MathUnsupportedOperationException}. However, the
1197     * returned vector is <em>not</em> immutable, since any modification of
1198     * {@code v} will also change the returned view.
1199     * For example, in the following piece of code
1200     * <pre>
1201     *     RealVector v = new ArrayRealVector(2);
1202     *     RealVector w = RealVector.unmodifiableRealVector(v);
1203     *     v.setEntry(0, 1.2);
1204     *     v.setEntry(1, -3.4);
1205     * </pre>
1206     * the changes will be seen in the {@code w} view of {@code v}.
1207     *
1208     * @param v Vector for which an unmodifiable view is to be returned.
1209     * @return an unmodifiable view of {@code v}.
1210     */
1211    public static RealVector unmodifiableRealVector(final RealVector v) {
1212        /*
1213         * This anonymous class is an implementation of {@link RealVector}
1214         * with read-only access.
1215         * It wraps any {@link RealVector}, and exposes all methods which
1216         * do not modify it. Invoking methods which should normally result
1217         * in the modification of the calling {@link RealVector} results in
1218         * a {@link MathUnsupportedOperationException}. It should be noted
1219         * that {@link UnmodifiableVector} is <em>not</em> immutable.
1220         */
1221        return new RealVector() {
1222            /**
1223             * {@inheritDoc}
1224             *
1225             * @throws MathUnsupportedOperationException in all circumstances.
1226             */
1227            @Override
1228            public RealVector mapToSelf(UnivariateFunction function)
1229                throws MathUnsupportedOperationException {
1230                throw new MathUnsupportedOperationException();
1231            }
1232
1233            /** {@inheritDoc} */
1234            @Override
1235            public RealVector map(UnivariateFunction function) {
1236                return v.map(function);
1237            }
1238
1239            /** {@inheritDoc} */
1240            @Override
1241            public Iterator<Entry> iterator() {
1242                final Iterator<Entry> i = v.iterator();
1243                return new Iterator<Entry>() {
1244                    /** The current entry. */
1245                    private final UnmodifiableEntry e = new UnmodifiableEntry();
1246
1247                    /** {@inheritDoc} */
1248                    @Override
1249                    public boolean hasNext() {
1250                        return i.hasNext();
1251                    }
1252
1253                    /** {@inheritDoc} */
1254                    @Override
1255                    public Entry next() {
1256                        e.setIndex(i.next().getIndex());
1257                        return e;
1258                    }
1259
1260                    /**
1261                     * {@inheritDoc}
1262                     *
1263                     * @throws MathUnsupportedOperationException in all
1264                     * circumstances.
1265                     */
1266                    @Override
1267                    public void remove() throws MathUnsupportedOperationException {
1268                        throw new MathUnsupportedOperationException();
1269                    }
1270                };
1271            }
1272
1273            /** {@inheritDoc} */
1274            @Override
1275            public Iterator<Entry> sparseIterator() {
1276                final Iterator<Entry> i = v.sparseIterator();
1277
1278                return new Iterator<Entry>() {
1279                    /** The current entry. */
1280                    private final UnmodifiableEntry e = new UnmodifiableEntry();
1281
1282                    /** {@inheritDoc} */
1283                    @Override
1284                    public boolean hasNext() {
1285                        return i.hasNext();
1286                    }
1287
1288                    /** {@inheritDoc} */
1289                    @Override
1290                    public Entry next() {
1291                        e.setIndex(i.next().getIndex());
1292                        return e;
1293                    }
1294
1295                    /**
1296                     * {@inheritDoc}
1297                     *
1298                     * @throws MathUnsupportedOperationException in all
1299                     * circumstances.
1300                     */
1301                    @Override
1302                    public void remove()
1303                        throws MathUnsupportedOperationException {
1304                        throw new MathUnsupportedOperationException();
1305                    }
1306                };
1307            }
1308
1309            /** {@inheritDoc} */
1310            @Override
1311            public RealVector copy() {
1312                return v.copy();
1313            }
1314
1315            /** {@inheritDoc} */
1316            @Override
1317            public RealVector add(RealVector w)
1318                throws DimensionMismatchException {
1319                return v.add(w);
1320            }
1321
1322            /** {@inheritDoc} */
1323            @Override
1324            public RealVector subtract(RealVector w)
1325                throws DimensionMismatchException {
1326                return v.subtract(w);
1327            }
1328
1329            /** {@inheritDoc} */
1330            @Override
1331            public RealVector mapAdd(double d) {
1332                return v.mapAdd(d);
1333            }
1334
1335            /**
1336             * {@inheritDoc}
1337             *
1338             * @throws MathUnsupportedOperationException in all
1339             * circumstances.
1340             */
1341            @Override
1342            public RealVector mapAddToSelf(double d)
1343                throws MathUnsupportedOperationException {
1344                throw new MathUnsupportedOperationException();
1345            }
1346
1347            /** {@inheritDoc} */
1348            @Override
1349            public RealVector mapSubtract(double d) {
1350                return v.mapSubtract(d);
1351            }
1352
1353            /**
1354             * {@inheritDoc}
1355             *
1356             * @throws MathUnsupportedOperationException in all
1357             * circumstances.
1358             */
1359            @Override
1360            public RealVector mapSubtractToSelf(double d)
1361                throws MathUnsupportedOperationException {
1362                throw new MathUnsupportedOperationException();
1363            }
1364
1365            /** {@inheritDoc} */
1366            @Override
1367            public RealVector mapMultiply(double d) {
1368                return v.mapMultiply(d);
1369            }
1370
1371            /**
1372             * {@inheritDoc}
1373             *
1374             * @throws MathUnsupportedOperationException in all
1375             * circumstances.
1376             */
1377            @Override
1378            public RealVector mapMultiplyToSelf(double d)
1379                throws MathUnsupportedOperationException {
1380                throw new MathUnsupportedOperationException();
1381            }
1382
1383            /** {@inheritDoc} */
1384            @Override
1385            public RealVector mapDivide(double d) {
1386                return v.mapDivide(d);
1387            }
1388
1389            /**
1390             * {@inheritDoc}
1391             *
1392             * @throws MathUnsupportedOperationException in all
1393             * circumstances.
1394             */
1395            @Override
1396            public RealVector mapDivideToSelf(double d)
1397                throws MathUnsupportedOperationException {
1398                throw new MathUnsupportedOperationException();
1399            }
1400
1401            /** {@inheritDoc} */
1402            @Override
1403            public RealVector ebeMultiply(RealVector w)
1404                throws DimensionMismatchException {
1405                return v.ebeMultiply(w);
1406            }
1407
1408            /** {@inheritDoc} */
1409            @Override
1410            public RealVector ebeDivide(RealVector w)
1411                throws DimensionMismatchException {
1412                return v.ebeDivide(w);
1413            }
1414
1415            /** {@inheritDoc} */
1416            @Override
1417            public double dotProduct(RealVector w)
1418                throws DimensionMismatchException {
1419                return v.dotProduct(w);
1420            }
1421
1422            /** {@inheritDoc} */
1423            @Override
1424            public double cosine(RealVector w)
1425                throws DimensionMismatchException, MathArithmeticException {
1426                return v.cosine(w);
1427            }
1428
1429            /** {@inheritDoc} */
1430            @Override
1431            public double getNorm() {
1432                return v.getNorm();
1433            }
1434
1435            /** {@inheritDoc} */
1436            @Override
1437            public double getL1Norm() {
1438                return v.getL1Norm();
1439            }
1440
1441            /** {@inheritDoc} */
1442            @Override
1443            public double getLInfNorm() {
1444                return v.getLInfNorm();
1445            }
1446
1447            /** {@inheritDoc} */
1448            @Override
1449            public double getDistance(RealVector w)
1450                throws DimensionMismatchException {
1451                return v.getDistance(w);
1452            }
1453
1454            /** {@inheritDoc} */
1455            @Override
1456            public double getL1Distance(RealVector w)
1457                throws DimensionMismatchException {
1458                return v.getL1Distance(w);
1459            }
1460
1461            /** {@inheritDoc} */
1462            @Override
1463            public double getLInfDistance(RealVector w)
1464                throws DimensionMismatchException {
1465                return v.getLInfDistance(w);
1466            }
1467
1468            /** {@inheritDoc} */
1469            @Override
1470            public RealVector unitVector() throws MathArithmeticException {
1471                return v.unitVector();
1472            }
1473
1474            /**
1475             * {@inheritDoc}
1476             *
1477             * @throws MathUnsupportedOperationException in all
1478             * circumstances.
1479             */
1480            @Override
1481            public void unitize() throws MathUnsupportedOperationException {
1482                throw new MathUnsupportedOperationException();
1483            }
1484
1485            /** {@inheritDoc} */
1486            @Override
1487            public RealMatrix outerProduct(RealVector w) {
1488                return v.outerProduct(w);
1489            }
1490
1491            /** {@inheritDoc} */
1492            @Override
1493            public double getEntry(int index) throws OutOfRangeException {
1494                return v.getEntry(index);
1495            }
1496
1497            /**
1498             * {@inheritDoc}
1499             *
1500             * @throws MathUnsupportedOperationException in all
1501             * circumstances.
1502             */
1503            @Override
1504            public void setEntry(int index, double value)
1505                throws MathUnsupportedOperationException {
1506                throw new MathUnsupportedOperationException();
1507            }
1508
1509            /**
1510             * {@inheritDoc}
1511             *
1512             * @throws MathUnsupportedOperationException in all
1513             * circumstances.
1514             */
1515            @Override
1516            public void addToEntry(int index, double value)
1517                throws MathUnsupportedOperationException {
1518                throw new MathUnsupportedOperationException();
1519            }
1520
1521            /** {@inheritDoc} */
1522            @Override
1523            public int getDimension() {
1524                return v.getDimension();
1525            }
1526
1527            /** {@inheritDoc} */
1528            @Override
1529            public RealVector append(RealVector w) {
1530                return v.append(w);
1531            }
1532
1533            /** {@inheritDoc} */
1534            @Override
1535            public RealVector append(double d) {
1536                return v.append(d);
1537            }
1538
1539            /** {@inheritDoc} */
1540            @Override
1541            public RealVector getSubVector(int index, int n)
1542                throws OutOfRangeException, NotPositiveException {
1543                return v.getSubVector(index, n);
1544            }
1545
1546            /**
1547             * {@inheritDoc}
1548             *
1549             * @throws MathUnsupportedOperationException in all
1550             * circumstances.
1551             */
1552            @Override
1553            public void setSubVector(int index, RealVector w)
1554                throws MathUnsupportedOperationException {
1555                throw new MathUnsupportedOperationException();
1556            }
1557
1558            /**
1559             * {@inheritDoc}
1560             *
1561             * @throws MathUnsupportedOperationException in all
1562             * circumstances.
1563             */
1564            @Override
1565            public void set(double value)
1566                throws MathUnsupportedOperationException {
1567                throw new MathUnsupportedOperationException();
1568            }
1569
1570            /** {@inheritDoc} */
1571            @Override
1572            public double[] toArray() {
1573                return v.toArray();
1574            }
1575
1576            /** {@inheritDoc} */
1577            @Override
1578            public boolean isNaN() {
1579                return v.isNaN();
1580            }
1581
1582            /** {@inheritDoc} */
1583            @Override
1584            public boolean isInfinite() {
1585                return v.isInfinite();
1586            }
1587
1588            /** {@inheritDoc} */
1589            @Override
1590            public RealVector combine(double a, double b, RealVector y)
1591                throws DimensionMismatchException {
1592                return v.combine(a, b, y);
1593            }
1594
1595            /**
1596             * {@inheritDoc}
1597             *
1598             * @throws MathUnsupportedOperationException in all
1599             * circumstances.
1600             */
1601            @Override
1602            public RealVector combineToSelf(double a, double b, RealVector y)
1603                throws MathUnsupportedOperationException {
1604                throw new MathUnsupportedOperationException();
1605            }
1606
1607            /** An entry in the vector. */
1608            class UnmodifiableEntry extends Entry {
1609                /** {@inheritDoc} */
1610                @Override
1611                public double getValue() {
1612                    return v.getEntry(getIndex());
1613                }
1614
1615                /**
1616                 * {@inheritDoc}
1617                 *
1618                 * @throws MathUnsupportedOperationException in all
1619                 * circumstances.
1620                 */
1621                @Override
1622                public void setValue(double value)
1623                    throws MathUnsupportedOperationException {
1624                    throw new MathUnsupportedOperationException();
1625                }
1626            }
1627        };
1628    }
1629}