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