001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.linear;
019    
020    import java.util.Iterator;
021    import java.util.NoSuchElementException;
022    
023    import org.apache.commons.math.exception.MathUnsupportedOperationException;
024    import org.apache.commons.math.exception.DimensionMismatchException;
025    import org.apache.commons.math.exception.OutOfRangeException;
026    import org.apache.commons.math.exception.MathArithmeticException;
027    import org.apache.commons.math.analysis.FunctionUtils;
028    import org.apache.commons.math.analysis.function.Add;
029    import org.apache.commons.math.analysis.function.Multiply;
030    import org.apache.commons.math.analysis.function.Divide;
031    import org.apache.commons.math.analysis.UnivariateRealFunction;
032    import org.apache.commons.math.exception.util.LocalizedFormats;
033    import org.apache.commons.math.util.FastMath;
034    
035    /**
036     * Class defining a real-valued vector with basic algebraic operations.
037     * <p>
038     * vector element indexing is 0-based -- e.g., {@code getEntry(0)}
039     * returns the first element of the vector.
040     * </p>
041     * <p>
042     * The {@code code map} and {@code mapToSelf} methods operate
043     * on vectors element-wise, i.e. they perform the same operation (adding a scalar,
044     * applying a function ...) on each element in turn. The {@code map}
045     * versions create a new vector to hold the result and do not change the instance.
046     * The {@code mapToSelf} version uses the instance itself to store the
047     * results, so the instance is changed by this method. In all cases, the result
048     * vector is returned by the methods, allowing the <i>fluent API</i>
049     * style, like this:
050     * </p>
051     * <pre>
052     *   RealVector result = v.mapAddToSelf(3.4).mapToSelf(new Tan()).mapToSelf(new Power(2.3));
053     * </pre>
054     *
055     * @version $Id: RealVector.java 1185398 2011-10-17 22:10:42Z erans $
056     * @since 2.1
057     */
058    public abstract class RealVector {
059        /**
060         * Returns the size of the vector.
061         *
062         * @return the size of this vector.
063         */
064        public abstract int getDimension();
065    
066        /**
067         * Return the entry at the specified index.
068         *
069         * @param index Index location of entry to be fetched.
070         * @return the vector entry at {@code index}.
071         * @throws org.apache.commons.math.exception.OutOfRangeException
072         * if the index is not valid.
073         * @see #setEntry(int, double)
074         */
075        public abstract double getEntry(int index);
076    
077        /**
078         * Set a single element.
079         *
080         * @param index element index.
081         * @param value new value for the element.
082         * @throws org.apache.commons.math.exception.OutOfRangeException
083         * if the index is not valid.
084         * @see #getEntry(int)
085         */
086        public abstract void setEntry(int index, double value);
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 org.apache.commons.math.exception.OutOfRangeException if
094         * the index is not valid.
095         * @since 3.0
096         */
097        public void addToEntry(int index, double increment) {
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 org.apache.commons.math.exception.OutOfRangeException
124         * if the index is not valid.
125         */
126        public abstract RealVector getSubVector(int index, int n);
127    
128        /**
129         * Set a sequence of consecutive elements.
130         *
131         * @param index index of first element to be set.
132         * @param v vector containing the values to set.
133         * @throws org.apache.commons.math.exception.OutOfRangeException
134         * if the index is not valid.
135         */
136        public abstract void setSubVector(int index, RealVector v);
137    
138        /**
139         * Check whether any coordinate of this vector is {@code NaN}.
140         *
141         * @return {@code true} if any coordinate of this vector is {@code NaN},
142         * {@code false} otherwise.
143         */
144        public abstract boolean isNaN();
145    
146        /**
147         * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
148         *
149         * @return {@code true} if any coordinate of this vector is infinite and
150         * none are {@code NaN}, {@code false} otherwise.
151         */
152        public abstract boolean isInfinite();
153    
154        /**
155         * Check if instance and specified vectors have the same dimension.
156         *
157         * @param v Vector to compare instance with.
158         * @throws DimensionMismatchException if the vectors do not
159         * have the same dimension.
160         */
161        protected void checkVectorDimensions(RealVector v) {
162            checkVectorDimensions(v.getDimension());
163        }
164    
165        /**
166         * Check if instance dimension is equal to some expected value.
167         *
168         * @param n Expected dimension.
169         * @throws DimensionMismatchException if the dimension is
170         * inconsistent with the vector size.
171         */
172        protected void checkVectorDimensions(int n) {
173            int d = getDimension();
174            if (d != n) {
175                throw new DimensionMismatchException(d, n);
176            }
177        }
178    
179        /**
180         * Check if an index is valid.
181         *
182         * @param index Index to check.
183         * @exception OutOfRangeException if {@code index} is not valid.
184         */
185        protected void checkIndex(final int index) {
186            if (index < 0 ||
187                index >= getDimension()) {
188                throw new OutOfRangeException(LocalizedFormats.INDEX,
189                                              index, 0, getDimension() - 1);
190            }
191        }
192    
193        /**
194         * Compute the sum of this vector and {@code v}.
195         * Returns a new vector. Does not change instance data.
196         *
197         * @param v Vector to be added.
198         * @return {@code this} + {@code v}.
199         * @throws org.apache.commons.math.exception.DimensionMismatchException
200         * if {@code v} is not the same size as this vector.
201         */
202        public RealVector add(RealVector v) {
203            RealVector result = v.copy();
204            Iterator<Entry> it = sparseIterator();
205            Entry e;
206            while (it.hasNext() && (e = it.next()) != null) {
207                final int index = e.getIndex();
208                result.setEntry(index, e.getValue() + result.getEntry(index));
209            }
210            return result;
211        }
212    
213        /**
214         * Subtract {@code v} from this vector.
215         * Returns a new vector. Does not change instance data.
216         *
217         * @param v Vector to be subtracted.
218         * @return {@code this} - {@code v}.
219         * @throws org.apache.commons.math.exception.DimensionMismatchException
220         * if {@code v} is not the same size as this vector.
221         */
222        public RealVector subtract(RealVector v) {
223            RealVector result = v.copy();
224            Iterator<Entry> it = sparseIterator();
225            Entry e;
226            while (it.hasNext() && (e = it.next()) != null) {
227                final int index = e.getIndex();
228                result.setEntry(index, e.getValue() - result.getEntry(index));
229            }
230            return result;
231        }
232    
233        /**
234         * Add a value to each entry.
235         * Returns a new vector. Does not change instance data.
236         *
237         * @param d Value to be added to each entry.
238         * @return {@code this} + {@code d}.
239         */
240        public RealVector mapAdd(double d) {
241            return copy().mapAddToSelf(d);
242        }
243    
244        /**
245         * Add a value to each entry.
246         * The instance is changed in-place.
247         *
248         * @param d Value to be added to each entry.
249         * @return {@code this}.
250         */
251        public RealVector mapAddToSelf(double d) {
252            if (d != 0) {
253                return mapToSelf(FunctionUtils.fix2ndArgument(new Add(), d));
254            }
255            return this;
256        }
257    
258        /**
259         * Returns a (deep) copy of this vector.
260         *
261         * @return a vector copy.
262         */
263        public abstract RealVector copy();
264    
265        /**
266         * Compute the dot product of this vector with {@code v}.
267         *
268         * @param v Vector with which dot product should be computed
269         * @return the scalar dot product between this instance and {@code v}.
270         * @throws org.apache.commons.math.exception.DimensionMismatchException
271         * if {@code v} is not the same size as this vector.
272         */
273        public double dotProduct(RealVector v) {
274            checkVectorDimensions(v);
275            double d = 0;
276            Iterator<Entry> it = sparseIterator();
277            Entry e;
278            while (it.hasNext() && (e = it.next()) != null) {
279                d += e.getValue() * v.getEntry(e.getIndex());
280            }
281            return d;
282        }
283    
284        /**
285         * Computes the cosine of the angle between this vector and the
286         * argument.
287         *
288         * @param v Vector.
289         * @return the cosine of the angle between this vector and {@code v}.
290         */
291        public double cosine(RealVector v) {
292            final double norm = getNorm();
293            final double vNorm = v.getNorm();
294    
295            if (norm == 0 ||
296                vNorm == 0) {
297                throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
298            }
299            return dotProduct(v) / (norm * vNorm);
300        }
301    
302        /**
303         * Element-by-element division.
304         *
305         * @param v Vector by which instance elements must be divided.
306         * @return a vector containing this[i] / v[i] for all i.
307         * @throws org.apache.commons.math.exception.DimensionMismatchException
308         * if {@code v} is not the same size as this vector.
309         */
310        public abstract RealVector ebeDivide(RealVector v);
311    
312        /**
313         * Element-by-element multiplication.
314         *
315         * @param v Vector by which instance elements must be multiplied
316         * @return a vector containing this[i] * v[i] for all i.
317         * @throws org.apache.commons.math.exception.DimensionMismatchException
318         * if {@code v} is not the same size as this vector.
319         */
320        public abstract RealVector ebeMultiply(RealVector v);
321    
322        /**
323         * Distance between two vectors.
324         * <p>This method computes the distance consistent with the
325         * L<sub>2</sub> norm, i.e. the square root of the sum of
326         * element differences, or Euclidian distance.</p>
327         *
328         * @param v Vector to which distance is requested.
329         * @return the distance between two vectors.
330         * @throws org.apache.commons.math.exception.DimensionMismatchException
331         * if {@code v} is not the same size as this vector.
332         * @see #getL1Distance(RealVector)
333         * @see #getLInfDistance(RealVector)
334         * @see #getNorm()
335         */
336        public double getDistance(RealVector v) {
337            checkVectorDimensions(v);
338            double d = 0;
339            Iterator<Entry> it = iterator();
340            Entry e;
341            while (it.hasNext() && (e = it.next()) != null) {
342                final double diff = e.getValue() - v.getEntry(e.getIndex());
343                d += diff * diff;
344            }
345            return FastMath.sqrt(d);
346        }
347    
348        /**
349         * Returns the L<sub>2</sub> norm of the vector.
350         * <p>The L<sub>2</sub> norm is the root of the sum of
351         * the squared elements.</p>
352         *
353         * @return the norm.
354         * @see #getL1Norm()
355         * @see #getLInfNorm()
356         * @see #getDistance(RealVector)
357         */
358        public double getNorm() {
359            double sum = 0;
360            Iterator<Entry> it = sparseIterator();
361            Entry e;
362            while (it.hasNext() && (e = it.next()) != null) {
363                final double value = e.getValue();
364                sum += value * value;
365            }
366            return FastMath.sqrt(sum);
367        }
368    
369        /**
370         * Returns the L<sub>1</sub> norm of the vector.
371         * <p>The L<sub>1</sub> norm is the sum of the absolute
372         * values of the elements.</p>
373         *
374         * @return the norm.
375         * @see #getNorm()
376         * @see #getLInfNorm()
377         * @see #getL1Distance(RealVector)
378         */
379        public double getL1Norm() {
380            double norm = 0;
381            Iterator<Entry> it = sparseIterator();
382            Entry e;
383            while (it.hasNext() && (e = it.next()) != null) {
384                norm += FastMath.abs(e.getValue());
385            }
386            return norm;
387        }
388    
389        /**
390         * Returns the L<sub>&infin;</sub> norm of the vector.
391         * <p>The L<sub>&infin;</sub> norm is the max of the absolute
392         * values of the elements.</p>
393         *
394         * @return the norm.
395         * @see #getNorm()
396         * @see #getL1Norm()
397         * @see #getLInfDistance(RealVector)
398         */
399        public double getLInfNorm() {
400            double norm = 0;
401            Iterator<Entry> it = sparseIterator();
402            Entry e;
403            while (it.hasNext() && (e = it.next()) != null) {
404                norm = FastMath.max(norm, FastMath.abs(e.getValue()));
405            }
406            return norm;
407        }
408    
409        /**
410         * Distance between two vectors.
411         * <p>This method computes the distance consistent with
412         * L<sub>1</sub> norm, i.e. the sum of the absolute values of
413         * the elements differences.</p>
414         *
415         * @param v Vector to which distance is requested.
416         * @return the distance between two vectors.
417         * @throws org.apache.commons.math.exception.DimensionMismatchException
418         * if {@code v} is not the same size as this vector.
419         */
420        public double getL1Distance(RealVector v) {
421            checkVectorDimensions(v);
422            double d = 0;
423            Iterator<Entry> it = iterator();
424            Entry e;
425            while (it.hasNext() && (e = it.next()) != null) {
426                d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
427            }
428            return d;
429        }
430    
431        /**
432         * Distance between two vectors.
433         * <p>This method computes the distance consistent with
434         * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
435         * element differences.</p>
436         *
437         * @param v Vector to which distance is requested.
438         * @return the distance between two vectors.
439         * @throws org.apache.commons.math.exception.DimensionMismatchException
440         * if {@code v} is not the same size as this vector.
441         * @see #getDistance(RealVector)
442         * @see #getL1Distance(RealVector)
443         * @see #getLInfNorm()
444         */
445        public double getLInfDistance(RealVector v) {
446            checkVectorDimensions(v);
447            double d = 0;
448            Iterator<Entry> it = iterator();
449            Entry e;
450            while (it.hasNext() && (e = it.next()) != null) {
451                d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
452            }
453            return d;
454        }
455    
456        /**
457         * Get the index of the minimum entry.
458         *
459         * @return the index of the minimum entry or -1 if vector length is 0
460         * or all entries are {@code NaN}.
461         */
462        public int getMinIndex() {
463            int minIndex    = -1;
464            double minValue = Double.POSITIVE_INFINITY;
465            Iterator<Entry> iterator = iterator();
466            while (iterator.hasNext()) {
467                final Entry entry = iterator.next();
468                if (entry.getValue() <= minValue) {
469                    minIndex = entry.getIndex();
470                    minValue = entry.getValue();
471                }
472            }
473            return minIndex;
474        }
475    
476        /**
477         * Get the value of the minimum entry.
478         *
479         * @return the value of the minimum entry or {@code NaN} if all
480         * entries are {@code NaN}.
481         */
482        public double getMinValue() {
483            final int minIndex = getMinIndex();
484            return minIndex < 0 ? Double.NaN : getEntry(minIndex);
485        }
486    
487        /**
488         * Get the index of the maximum entry.
489         *
490         * @return the index of the maximum entry or -1 if vector length is 0
491         * or all entries are {@code NaN}
492         */
493        public int getMaxIndex() {
494            int maxIndex    = -1;
495            double maxValue = Double.NEGATIVE_INFINITY;
496            Iterator<Entry> iterator = iterator();
497            while (iterator.hasNext()) {
498                final Entry entry = iterator.next();
499                if (entry.getValue() >= maxValue) {
500                    maxIndex = entry.getIndex();
501                    maxValue = entry.getValue();
502                }
503            }
504            return maxIndex;
505        }
506    
507        /**
508         * Get the value of the maximum entry.
509         *
510         * @return the value of the maximum entry or {@code NaN} if all
511         * entries are {@code NaN}.
512         */
513        public double getMaxValue() {
514            final int maxIndex = getMaxIndex();
515            return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
516        }
517    
518    
519        /**
520         * Multiply each entry by the argument. Returns a new vector.
521         * Does not change instance data.
522         *
523         * @param d Multiplication factor.
524         * @return {@code this} * {@code d}.
525         */
526        public RealVector mapMultiply(double d) {
527            return copy().mapMultiplyToSelf(d);
528        }
529    
530        /**
531         * Multiply each entry.
532         * The instance is changed in-place.
533         *
534         * @param d Multiplication factor.
535         * @return {@code this}.
536         */
537        public RealVector mapMultiplyToSelf(double d){
538            return mapToSelf(FunctionUtils.fix2ndArgument(new Multiply(), d));
539        }
540    
541        /**
542         * Subtract a value from each entry. Returns a new vector.
543         * Does not change instance data.
544         *
545         * @param d Value to be subtracted.
546         * @return {@code this} - {@code d}.
547         */
548        public RealVector mapSubtract(double d) {
549            return copy().mapSubtractToSelf(d);
550        }
551    
552        /**
553         * Subtract a value from each entry.
554         * The instance is changed in-place.
555         *
556         * @param d Value to be subtracted.
557         * @return {@code this}.
558         */
559        public RealVector mapSubtractToSelf(double d){
560            return mapAddToSelf(-d);
561        }
562    
563        /**
564         * Divide each entry by the argument. Returns a new vector.
565         * Does not change instance data.
566         *
567         * @param d Value to divide by.
568         * @return {@code this} / {@code d}.
569         */
570        public RealVector mapDivide(double d) {
571            return copy().mapDivideToSelf(d);
572        }
573    
574        /**
575         * Divide each entry by the argument.
576         * The instance is changed in-place.
577         *
578         * @param d Value to divide by.
579         * @return {@code this}.
580         */
581        public RealVector mapDivideToSelf(double d){
582            return mapToSelf(FunctionUtils.fix2ndArgument(new Divide(), d));
583        }
584    
585        /**
586         * Compute the outer product.
587         *
588         * @param v Vector with which outer product should be computed.
589         * @return the matrix outer product between this instance and {@code v}.
590         */
591        public RealMatrix outerProduct(RealVector v) {
592            RealMatrix product;
593            if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
594                product = new OpenMapRealMatrix(this.getDimension(),
595                                                v.getDimension());
596            } else {
597                product = new Array2DRowRealMatrix(this.getDimension(),
598                                                   v.getDimension());
599            }
600            Iterator<Entry> thisIt = sparseIterator();
601            Entry thisE = null;
602            while (thisIt.hasNext() && (thisE = thisIt.next()) != null) {
603                Iterator<Entry> otherIt = v.sparseIterator();
604                Entry otherE = null;
605                while (otherIt.hasNext() && (otherE = otherIt.next()) != null) {
606                    product.setEntry(thisE.getIndex(), otherE.getIndex(),
607                                     thisE.getValue() * otherE.getValue());
608                }
609            }
610    
611            return product;
612    
613        }
614    
615        /**
616         * Find the orthogonal projection of this vector onto another vector.
617         *
618         * @param v vector onto which instance must be projected.
619         * @return projection of the instance onto {@code v}.
620         * @throws org.apache.commons.math.exception.DimensionMismatchException
621         * if {@code v} is not the same size as this vector.
622         */
623        public abstract RealVector projection(RealVector v);
624    
625        /**
626         * Set all elements to a single value.
627         *
628         * @param value Single value to set for all elements.
629         */
630        public void set(double value) {
631            Iterator<Entry> it = iterator();
632            Entry e = null;
633            while (it.hasNext() && (e = it.next()) != null) {
634                e.setValue(value);
635            }
636        }
637    
638        /**
639         * Convert the vector to an array of {@code double}s.
640         * The array is independent from this vector data: the elements
641         * are copied.
642         *
643         * @return an array containing a copy of the vector elements.
644         */
645        public double[] toArray() {
646            int dim = getDimension();
647            double[] values = new double[dim];
648            for (int i = 0; i < dim; i++) {
649                values[i] = getEntry(i);
650            }
651            return values;
652        }
653    
654        /**
655         * Creates a unit vector pointing in the direction of this vector.
656         * The instance is not changed by this method.
657         *
658         * @return a unit vector pointing in direction of this vector.
659         * @throws ArithmeticException if the norm is {@code null}.
660         */
661        public RealVector unitVector() {
662            RealVector copy = copy();
663            copy.unitize();
664            return copy;
665        }
666    
667        /**
668         * Converts this vector into a unit vector.
669         * The instance itself is changed by this method.
670         *
671         * @throws org.apache.commons.math.exception.MathArithmeticException
672         * if the norm is zero.
673         */
674        public void unitize() {
675            mapDivideToSelf(getNorm());
676        }
677    
678        /**
679         * Create a sparse iterator over the vector, which may omit some entries.
680         * Specialized implementations may choose to not iterate over all
681         * dimensions, either because those values are unset, or are equal
682         * to defaultValue(), or are small enough to be ignored for the
683         * purposes of iteration. No guarantees are made about order of iteration.
684         * In dense implementations, this method will often delegate to
685         * {@link #iterator()}.
686         *
687         * @return a sparse iterator.
688         */
689        public Iterator<Entry> sparseIterator() {
690            return new SparseEntryIterator();
691        }
692    
693        /**
694         * Generic dense iterator. Iteration is in increasing order
695         * of the vector index.
696         *
697         * @return a dense iterator.
698         */
699        public Iterator<Entry> iterator() {
700            final int dim = getDimension();
701            return new Iterator<Entry>() {
702    
703                /** Current index. */
704                private int i = 0;
705    
706                /** Current entry. */
707                private Entry e = new Entry();
708    
709                /** {@inheritDoc} */
710                public boolean hasNext() {
711                    return i < dim;
712                }
713    
714                /** {@inheritDoc} */
715                public Entry next() {
716                    e.setIndex(i++);
717                    return e;
718                }
719    
720                /** {@inheritDoc} */
721                public void remove() {
722                    throw new MathUnsupportedOperationException();
723                }
724            };
725        }
726    
727        /**
728         * Acts as if implemented as:
729         * <pre>
730         *  return copy().mapToSelf(function);
731         * </pre>
732         * Returns a new vector. Does not change instance data.
733         *
734         * @param function Function to apply to each entry.
735         * @return a new vector.
736         */
737        public RealVector map(UnivariateRealFunction function) {
738            return copy().mapToSelf(function);
739        }
740    
741        /**
742         * Acts as if it is implemented as:
743         * <pre>
744         *  Entry e = null;
745         *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
746         *      e.setValue(function.value(e.getValue()));
747         *  }
748         * </pre>
749         * Entries of this vector are modified in-place by this method.
750         *
751         * @param function Function to apply to each entry.
752         * @return a reference to this vector.
753         */
754        public RealVector mapToSelf(UnivariateRealFunction function) {
755            Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator();
756            Entry e;
757            while (it.hasNext() && (e = it.next()) != null) {
758                e.setValue(function.value(e.getValue()));
759            }
760            return this;
761        }
762    
763        /**
764         * Returns a new vector representing {@code a * this + b * y}, the linear
765         * combination of {@code this} and {@code y}.
766         * Returns a new vector. Does not change instance data.
767         *
768         * @param a Coefficient of {@code this}.
769         * @param b Coefficient of {@code y}.
770         * @param y Vector with which {@code this} is linearly combined.
771         * @return a vector containing {@code a * this[i] + b * y[i]} for all
772         * {@code i}.
773         * @throws org.apache.commons.math.exception.DimensionMismatchException
774         * if {@code y} is not the same size as this vector.
775         */
776        public RealVector combine(double a, double b, RealVector y) {
777            return copy().combineToSelf(a, b, y);
778        }
779    
780        /**
781         * Updates {@code this} with the linear combination of {@code this} and
782         * {@code y}.
783         *
784         * @param a Weight of {@code this}.
785         * @param b Weight of {@code y}.
786         * @param y Vector with which {@code this} is linearly combined.
787         * @return {@code this}, with components equal to
788         * {@code a * this[i] + b * y[i]} for all {@code i}.
789         * @throws org.apache.commons.math.exception.DimensionMismatchException
790         * if {@code y} is not the same size as this vector.
791         */
792        public RealVector combineToSelf(double a, double b, RealVector y) {
793            checkVectorDimensions(y);
794            for (int i = 0; i < getDimension(); i++) {
795                final double xi = getEntry(i);
796                final double yi = y.getEntry(i);
797                setEntry(i, a * xi + b * yi);
798            }
799            return this;
800        }
801    
802        /**
803         *  An entry in the vector.
804         */
805        protected class Entry {
806            /** Index of this entry. */
807            private int index;
808    
809            /** Simple constructor. */
810            public Entry() {
811                setIndex(0);
812            }
813    
814            /**
815             * Get the value of the entry.
816             *
817             * @return the value of the entry.
818             */
819            public double getValue() {
820                return getEntry(getIndex());
821            }
822    
823            /**
824             * Set the value of the entry.
825             *
826             * @param value New value for the entry.
827             */
828            public void setValue(double value) {
829                setEntry(getIndex(), value);
830            }
831    
832            /**
833             * Get the index of the entry.
834             *
835             * @return the index of the entry.
836             */
837            public int getIndex() {
838                return index;
839            }
840    
841            /**
842             * Set the index of the entry.
843             *
844             * @param index New index for the entry.
845             */
846            public void setIndex(int index) {
847                this.index = index;
848            }
849        }
850    
851        /**
852         * This class should rarely be used, but is here to provide
853         * a default implementation of sparseIterator(), which is implemented
854         * by walking over the entries, skipping those whose values are the default one.
855         *
856         * Concrete subclasses which are SparseVector implementations should
857         * make their own sparse iterator, rather than using this one.
858         *
859         * This implementation might be useful for ArrayRealVector, when expensive
860         * operations which preserve the default value are to be done on the entries,
861         * and the fraction of non-default values is small (i.e. someone took a
862         * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
863         */
864        protected class SparseEntryIterator implements Iterator<Entry> {
865            /** Dimension of the vector. */
866            private final int dim;
867            /** Last entry returned by {@link #next()}. */
868            private Entry current;
869            /** Next entry for {@link #next()} to return. */
870            private Entry next;
871    
872            /** Simple constructor. */
873            protected SparseEntryIterator() {
874                dim = getDimension();
875                current = new Entry();
876                next = new Entry();
877                if (next.getValue() == 0) {
878                    advance(next);
879                }
880            }
881    
882            /**
883             * Advance an entry up to the next nonzero one.
884             *
885             * @param e entry to advance.
886             */
887            protected void advance(Entry e) {
888                if (e == null) {
889                    return;
890                }
891                do {
892                    e.setIndex(e.getIndex() + 1);
893                } while (e.getIndex() < dim && e.getValue() == 0);
894                if (e.getIndex() >= dim) {
895                    e.setIndex(-1);
896                }
897            }
898    
899            /** {@inheritDoc} */
900            public boolean hasNext() {
901                return next.getIndex() >= 0;
902            }
903    
904            /** {@inheritDoc} */
905            public Entry next() {
906                int index = next.getIndex();
907                if (index < 0) {
908                    throw new NoSuchElementException();
909                }
910                current.setIndex(index);
911                advance(next);
912                return current;
913            }
914    
915            /** {@inheritDoc} */
916            public void remove() {
917                throw new MathUnsupportedOperationException();
918            }
919        }
920    
921        /**
922         * Returns an unmodifiable view of the specified vector.
923         * The returned vector has read-only access. An attempt to modify it will
924         * result in a {@link MathUnsupportedOperationException}. However, the
925         * returned vector is <em>not</em> immutable, since any modification of
926         * {@code v} will also change the returned view.
927         * For example, in the following piece of code
928         * <pre>
929         *     RealVector v = new ArrayRealVector(2);
930         *     RealVector w = RealVector.unmodifiableRealVector(v);
931         *     v.setEntry(0, 1.2);
932         *     v.setEntry(1, -3.4);
933         * </pre>
934         * the changes will be seen in the {@code w} view of {@code v}.
935         *
936         * @param v Vector for which an unmodifiable view is to be returned.
937         * @return an unmodifiable view of {@code v}.
938         */
939        public static RealVector unmodifiableRealVector(final RealVector v) {
940            /**
941             * This anonymous class is an implementation of {@link RealVector}
942             * with read-only access.
943             * It wraps any {@link RealVector}, and exposes all methods which
944             * do not modify it. Invoking methods which should normally result
945             * in the modification of the calling {@link RealVector} results in
946             * a {@link MathUnsupportedOperationException}. It should be noted
947             * that {@link UnmodifiableVector} is <em>not</em> immutable.
948             */
949            return new RealVector() {
950                /** {@inheritDoc} */
951                @Override
952                public RealVector mapToSelf(UnivariateRealFunction function) {
953                    throw new MathUnsupportedOperationException();
954                }
955    
956                /** {@inheritDoc} */
957                @Override
958                public RealVector map(UnivariateRealFunction function) {
959                    return v.map(function);
960                }
961    
962                /** {@inheritDoc} */
963                @Override
964                public Iterator<Entry> iterator() {
965                    final Iterator<Entry> i = v.iterator();
966                    return new Iterator<Entry>() {
967                        /** The current entry. */
968                        private final UnmodifiableEntry e = new UnmodifiableEntry();
969    
970                        /** {@inheritDoc} */
971                        public boolean hasNext() {
972                            return i.hasNext();
973                        }
974    
975                        /** {@inheritDoc} */
976                        public Entry next() {
977                            e.setIndex(i.next().getIndex());
978                            return e;
979                        }
980    
981                        /** {@inheritDoc} */
982                        public void remove() {
983                            throw new MathUnsupportedOperationException();
984                        }
985                    };
986                }
987    
988                /** {@inheritDoc} */
989                @Override
990                public Iterator<Entry> sparseIterator() {
991                    final Iterator<Entry> i = v.sparseIterator();
992    
993                    return new Iterator<Entry>() {
994                        /** The current entry. */
995                        private final UnmodifiableEntry e = new UnmodifiableEntry();
996    
997                        /** {@inheritDoc} */
998                        public boolean hasNext() {
999                            return i.hasNext();
1000                        }
1001    
1002                        /** {@inheritDoc} */
1003                        public Entry next() {
1004                            e.setIndex(i.next().getIndex());
1005                            return e;
1006                        }
1007    
1008                        /** {@inheritDoc} */
1009                        public void remove() {
1010                            throw new MathUnsupportedOperationException();
1011                        }
1012                    };
1013                }
1014    
1015                /** {@inheritDoc} */
1016                @Override
1017                public RealVector copy() {
1018                    return v.copy();
1019                }
1020    
1021                /** {@inheritDoc} */
1022                @Override
1023                public RealVector add(RealVector w) {
1024                    return v.add(w);
1025                }
1026    
1027                /** {@inheritDoc} */
1028                @Override
1029                public RealVector subtract(RealVector w) {
1030                    return v.subtract(w);
1031                }
1032    
1033                /** {@inheritDoc} */
1034                @Override
1035                public RealVector mapAdd(double d) {
1036                    return v.mapAdd(d);
1037                }
1038    
1039                /** {@inheritDoc} */
1040                @Override
1041                public RealVector mapAddToSelf(double d) {
1042                    throw new MathUnsupportedOperationException();
1043                }
1044    
1045                /** {@inheritDoc} */
1046                @Override
1047                public RealVector mapSubtract(double d) {
1048                    return v.mapSubtract(d);
1049                }
1050    
1051                /** {@inheritDoc} */
1052                @Override
1053                public RealVector mapSubtractToSelf(double d) {
1054                    throw new MathUnsupportedOperationException();
1055                }
1056    
1057                /** {@inheritDoc} */
1058                @Override
1059                public RealVector mapMultiply(double d) {
1060                    return v.mapMultiply(d);
1061                }
1062    
1063                /** {@inheritDoc} */
1064                @Override
1065                public RealVector mapMultiplyToSelf(double d) {
1066                    throw new MathUnsupportedOperationException();
1067                }
1068    
1069                /** {@inheritDoc} */
1070                @Override
1071                public RealVector mapDivide(double d) {
1072                    return v.mapDivide(d);
1073                }
1074    
1075                /** {@inheritDoc} */
1076                @Override
1077                public RealVector mapDivideToSelf(double d) {
1078                    throw new MathUnsupportedOperationException();
1079                }
1080    
1081                /** {@inheritDoc} */
1082                @Override
1083                public RealVector ebeMultiply(RealVector w) {
1084                    return v.ebeMultiply(w);
1085                }
1086    
1087                /** {@inheritDoc} */
1088                @Override
1089                public RealVector ebeDivide(RealVector w) {
1090                    return v.ebeDivide(w);
1091                }
1092    
1093                /** {@inheritDoc} */
1094                @Override
1095                public double dotProduct(RealVector w) {
1096                    return v.dotProduct(w);
1097                }
1098    
1099                /** {@inheritDoc} */
1100                @Override
1101                public double cosine(RealVector w) {
1102                    return v.cosine(w);
1103                }
1104    
1105                /** {@inheritDoc} */
1106                @Override
1107                public double getNorm() {
1108                    return v.getNorm();
1109                }
1110    
1111                /** {@inheritDoc} */
1112                @Override
1113                public double getL1Norm() {
1114                    return v.getL1Norm();
1115                }
1116    
1117                /** {@inheritDoc} */
1118                @Override
1119                public double getLInfNorm() {
1120                    return v.getLInfNorm();
1121                }
1122    
1123                /** {@inheritDoc} */
1124                @Override
1125                public double getDistance(RealVector w) {
1126                    return v.getDistance(w);
1127                }
1128    
1129                /** {@inheritDoc} */
1130                @Override
1131                public double getL1Distance(RealVector w) {
1132                    return v.getL1Distance(w);
1133                }
1134    
1135                /** {@inheritDoc} */
1136                @Override
1137                public double getLInfDistance(RealVector w) {
1138                    return v.getLInfDistance(w);
1139                }
1140    
1141                /** {@inheritDoc} */
1142                @Override
1143                public RealVector unitVector() {
1144                    return v.unitVector();
1145                }
1146    
1147                /** {@inheritDoc} */
1148                @Override
1149                public void unitize() {
1150                    throw new MathUnsupportedOperationException();
1151                }
1152    
1153                /** {@inheritDoc} */
1154                @Override
1155                public RealVector projection(RealVector w) {
1156                    return v.projection(w);
1157                }
1158    
1159                /** {@inheritDoc} */
1160                @Override
1161                public RealMatrix outerProduct(RealVector w) {
1162                    return v.outerProduct(w);
1163                }
1164    
1165                /** {@inheritDoc} */
1166                @Override
1167                public double getEntry(int index) {
1168                    return v.getEntry(index);
1169                }
1170    
1171                /** {@inheritDoc} */
1172                @Override
1173                public void setEntry(int index, double value) {
1174                    throw new MathUnsupportedOperationException();
1175                }
1176    
1177                /** {@inheritDoc} */
1178                @Override
1179                public void addToEntry(int index, double value) {
1180                    throw new MathUnsupportedOperationException();
1181                }
1182    
1183                /** {@inheritDoc} */
1184                @Override
1185                public int getDimension() {
1186                    return v.getDimension();
1187                }
1188    
1189                /** {@inheritDoc} */
1190                @Override
1191                public RealVector append(RealVector w) {
1192                    return v.append(w);
1193                }
1194    
1195                /** {@inheritDoc} */
1196                @Override
1197                public RealVector append(double d) {
1198                    return v.append(d);
1199                }
1200    
1201                /** {@inheritDoc} */
1202                @Override
1203                public RealVector getSubVector(int index, int n) {
1204                    return v.getSubVector(index, n);
1205                }
1206    
1207                /** {@inheritDoc} */
1208                @Override
1209                public void setSubVector(int index, RealVector w) {
1210                    throw new MathUnsupportedOperationException();
1211                }
1212    
1213                /** {@inheritDoc} */
1214                @Override
1215                public void set(double value) {
1216                    throw new MathUnsupportedOperationException();
1217                }
1218    
1219                /** {@inheritDoc} */
1220                @Override
1221                public double[] toArray() {
1222                    return v.toArray();
1223                }
1224    
1225                /** {@inheritDoc} */
1226                @Override
1227                public boolean isNaN() {
1228                    return v.isNaN();
1229                }
1230    
1231                /** {@inheritDoc} */
1232                @Override
1233                public boolean isInfinite() {
1234                    return v.isInfinite();
1235                }
1236    
1237                /** {@inheritDoc} */
1238                @Override
1239                public RealVector combine(double a, double b, RealVector y) {
1240                    return v.combine(a, b, y);
1241                }
1242    
1243                /** {@inheritDoc} */
1244                @Override
1245                public RealVector combineToSelf(double a, double b, RealVector y) {
1246                    throw new MathUnsupportedOperationException();
1247                }
1248    
1249                /** An entry in the vector. */
1250                class UnmodifiableEntry extends Entry {
1251                    /** {@inheritDoc} */
1252                    @Override
1253                        public double getValue() {
1254                        return v.getEntry(getIndex());
1255                    }
1256    
1257                    /** {@inheritDoc} */
1258                    @Override
1259                        public void setValue(double value) {
1260                        throw new MathUnsupportedOperationException();
1261                    }
1262                }
1263            };
1264        }
1265    }