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.FunctionEvaluationException;
024    import org.apache.commons.math.exception.MathUnsupportedOperationException;
025    import org.apache.commons.math.exception.DimensionMismatchException;
026    import org.apache.commons.math.analysis.BinaryFunction;
027    import org.apache.commons.math.analysis.ComposableFunction;
028    import org.apache.commons.math.analysis.UnivariateRealFunction;
029    import org.apache.commons.math.exception.util.LocalizedFormats;
030    import org.apache.commons.math.util.FastMath;
031    
032    /**
033     * This class provides default basic implementations for many methods in the
034     * {@link RealVector} interface.
035     * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 f??vr. 2011) $
036     * @since 2.1
037     */
038    public abstract class AbstractRealVector implements RealVector {
039    
040        /**
041         * Check if instance and specified vectors have the same dimension.
042         * @param v vector to compare instance with
043         * @exception DimensionMismatchException if the vectors do not
044         * have the same dimension
045         */
046        protected void checkVectorDimensions(RealVector v) {
047            checkVectorDimensions(v.getDimension());
048        }
049    
050        /**
051         * Check if instance dimension is equal to some expected value.
052         *
053         * @param n expected dimension.
054         * @exception DimensionMismatchException if the dimension is
055         * inconsistent with vector size
056         */
057        protected void checkVectorDimensions(int n)
058            throws DimensionMismatchException {
059            int d = getDimension();
060            if (d != n) {
061                throw new DimensionMismatchException(d, n);
062            }
063        }
064    
065        /**
066         * Check if an index is valid.
067         * @param index index to check
068         * @exception MatrixIndexException if index is not valid
069         */
070        protected void checkIndex(final int index)
071            throws MatrixIndexException {
072            if (index < 0 || index >= getDimension()) {
073                throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE,
074                                               index, 0, getDimension() - 1);
075            }
076        }
077    
078        /** {@inheritDoc} */
079        public void setSubVector(int index, RealVector v) throws MatrixIndexException {
080            checkIndex(index);
081            checkIndex(index + v.getDimension() - 1);
082            setSubVector(index, v.getData());
083        }
084    
085        /** {@inheritDoc} */
086        public void setSubVector(int index, double[] v) throws MatrixIndexException {
087            checkIndex(index);
088            checkIndex(index + v.length - 1);
089            for (int i = 0; i < v.length; i++) {
090                setEntry(i + index, v[i]);
091            }
092        }
093    
094        /** {@inheritDoc} */
095        public RealVector add(double[] v) throws IllegalArgumentException {
096            double[] result = v.clone();
097            Iterator<Entry> it = sparseIterator();
098            Entry e;
099            while (it.hasNext() && (e = it.next()) != null) {
100                result[e.getIndex()] += e.getValue();
101            }
102            return new ArrayRealVector(result, false);
103        }
104    
105        /** {@inheritDoc} */
106        public RealVector add(RealVector v) throws IllegalArgumentException {
107            if (v instanceof ArrayRealVector) {
108                double[] values = ((ArrayRealVector)v).getDataRef();
109                return add(values);
110            }
111            RealVector result = v.copy();
112            Iterator<Entry> it = sparseIterator();
113            Entry e;
114            while (it.hasNext() && (e = it.next()) != null) {
115                final int index = e.getIndex();
116                result.setEntry(index, e.getValue() + result.getEntry(index));
117            }
118            return result;
119        }
120    
121        /** {@inheritDoc} */
122        public RealVector subtract(double[] v) throws IllegalArgumentException {
123            double[] result = v.clone();
124            Iterator<Entry> it = sparseIterator();
125            Entry e;
126            while (it.hasNext() && (e = it.next()) != null) {
127                final int index = e.getIndex();
128                result[index] = e.getValue() - result[index];
129            }
130            return new ArrayRealVector(result, false);
131        }
132    
133        /** {@inheritDoc} */
134        public RealVector subtract(RealVector v) throws IllegalArgumentException {
135            if (v instanceof ArrayRealVector) {
136                double[] values = ((ArrayRealVector)v).getDataRef();
137                return add(values);
138            }
139            RealVector result = v.copy();
140            Iterator<Entry> it = sparseIterator();
141            Entry e;
142            while (it.hasNext() && (e = it.next()) != null) {
143                final int index = e.getIndex();
144                v.setEntry(index, e.getValue() - result.getEntry(index));
145            }
146            return result;
147        }
148    
149        /** {@inheritDoc} */
150        public RealVector mapAdd(double d) {
151            return copy().mapAddToSelf(d);
152        }
153    
154        /** {@inheritDoc} */
155        public RealVector mapAddToSelf(double d) {
156            if (d != 0) {
157                try {
158                    return mapToSelf(BinaryFunction.ADD.fix1stArgument(d));
159                } catch (FunctionEvaluationException e) {
160                    throw new IllegalArgumentException(e);
161                }
162            }
163            return this;
164        }
165    
166        /** {@inheritDoc} */
167        public abstract AbstractRealVector copy();
168    
169        /** {@inheritDoc} */
170        public double dotProduct(double[] v) throws IllegalArgumentException {
171            return dotProduct(new ArrayRealVector(v, false));
172        }
173    
174        /** {@inheritDoc} */
175        public double dotProduct(RealVector v) throws IllegalArgumentException {
176            checkVectorDimensions(v);
177            double d = 0;
178            Iterator<Entry> it = sparseIterator();
179            Entry e;
180            while (it.hasNext() && (e = it.next()) != null) {
181                d += e.getValue() * v.getEntry(e.getIndex());
182            }
183            return d;
184        }
185    
186        /** {@inheritDoc} */
187        public RealVector ebeDivide(double[] v) throws IllegalArgumentException {
188            return ebeDivide(new ArrayRealVector(v, false));
189        }
190    
191        /** {@inheritDoc} */
192        public RealVector ebeMultiply(double[] v) throws IllegalArgumentException {
193            return ebeMultiply(new ArrayRealVector(v, false));
194        }
195    
196        /** {@inheritDoc} */
197        public double getDistance(RealVector v) throws IllegalArgumentException {
198            checkVectorDimensions(v);
199            double d = 0;
200            Iterator<Entry> it = iterator();
201            Entry e;
202            while (it.hasNext() && (e = it.next()) != null) {
203                final double diff = e.getValue() - v.getEntry(e.getIndex());
204                d += diff * diff;
205            }
206            return FastMath.sqrt(d);
207        }
208    
209        /** {@inheritDoc} */
210        public double getNorm() {
211            double sum = 0;
212            Iterator<Entry> it = sparseIterator();
213            Entry e;
214            while (it.hasNext() && (e = it.next()) != null) {
215                final double value = e.getValue();
216                sum += value * value;
217            }
218            return FastMath.sqrt(sum);
219        }
220    
221        /** {@inheritDoc} */
222        public double getL1Norm() {
223            double norm = 0;
224            Iterator<Entry> it = sparseIterator();
225            Entry e;
226            while (it.hasNext() && (e = it.next()) != null) {
227                norm += FastMath.abs(e.getValue());
228            }
229            return norm;
230        }
231    
232        /** {@inheritDoc} */
233        public double getLInfNorm() {
234            double norm = 0;
235            Iterator<Entry> it = sparseIterator();
236            Entry e;
237            while (it.hasNext() && (e = it.next()) != null) {
238                norm = FastMath.max(norm, FastMath.abs(e.getValue()));
239            }
240            return norm;
241        }
242    
243        /** {@inheritDoc} */
244        public double getDistance(double[] v) throws IllegalArgumentException {
245            return getDistance(new ArrayRealVector(v,false));
246        }
247    
248        /** {@inheritDoc} */
249        public double getL1Distance(RealVector v) throws IllegalArgumentException {
250            checkVectorDimensions(v);
251            double d = 0;
252            Iterator<Entry> it = iterator();
253            Entry e;
254            while (it.hasNext() && (e = it.next()) != null) {
255                d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
256            }
257            return d;
258        }
259    
260        /** {@inheritDoc} */
261        public double getL1Distance(double[] v) throws IllegalArgumentException {
262            checkVectorDimensions(v.length);
263            double d = 0;
264            Iterator<Entry> it = iterator();
265            Entry e;
266            while (it.hasNext() && (e = it.next()) != null) {
267                d += FastMath.abs(e.getValue() - v[e.getIndex()]);
268            }
269            return d;
270        }
271    
272        /** {@inheritDoc} */
273        public double getLInfDistance(RealVector v) throws IllegalArgumentException {
274            checkVectorDimensions(v);
275            double d = 0;
276            Iterator<Entry> it = iterator();
277            Entry e;
278            while (it.hasNext() && (e = it.next()) != null) {
279                d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
280            }
281            return d;
282        }
283    
284        /** {@inheritDoc} */
285        public double getLInfDistance(double[] v) throws IllegalArgumentException {
286            checkVectorDimensions(v.length);
287            double d = 0;
288            Iterator<Entry> it = iterator();
289            Entry e;
290            while (it.hasNext() && (e = it.next()) != null) {
291                d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d);
292            }
293            return d;
294        }
295    
296        /** Get the index of the minimum entry.
297         * @return index of the minimum entry or -1 if vector length is 0
298         * or all entries are NaN
299         */
300        public int getMinIndex() {
301            int minIndex    = -1;
302            double minValue = Double.POSITIVE_INFINITY;
303            Iterator<Entry> iterator = iterator();
304            while (iterator.hasNext()) {
305                final Entry entry = iterator.next();
306                if (entry.getValue() <= minValue) {
307                    minIndex = entry.getIndex();
308                    minValue = entry.getValue();
309                }
310            }
311            return minIndex;
312        }
313    
314        /** Get the value of the minimum entry.
315         * @return value of the minimum entry or NaN if all entries are NaN
316         */
317        public double getMinValue() {
318            final int minIndex = getMinIndex();
319            return minIndex < 0 ? Double.NaN : getEntry(minIndex);
320        }
321    
322        /** Get the index of the maximum entry.
323         * @return index of the maximum entry or -1 if vector length is 0
324         * or all entries are NaN
325         */
326        public int getMaxIndex() {
327            int maxIndex    = -1;
328            double maxValue = Double.NEGATIVE_INFINITY;
329            Iterator<Entry> iterator = iterator();
330            while (iterator.hasNext()) {
331                final Entry entry = iterator.next();
332                if (entry.getValue() >= maxValue) {
333                    maxIndex = entry.getIndex();
334                    maxValue = entry.getValue();
335                }
336            }
337            return maxIndex;
338        }
339    
340        /** Get the value of the maximum entry.
341         * @return value of the maximum entry or NaN if all entries are NaN
342         */
343        public double getMaxValue() {
344            final int maxIndex = getMaxIndex();
345            return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
346        }
347    
348        /** {@inheritDoc} */
349        public RealVector mapAbs() {
350            return copy().mapAbsToSelf();
351        }
352    
353        /** {@inheritDoc} */
354        public RealVector mapAbsToSelf() {
355            try {
356                return mapToSelf(ComposableFunction.ABS);
357            } catch (FunctionEvaluationException e) {
358                throw new IllegalArgumentException(e);
359            }
360        }
361    
362        /** {@inheritDoc} */
363        public RealVector mapAcos() {
364            return copy().mapAcosToSelf();
365        }
366    
367        /** {@inheritDoc} */
368        public RealVector mapAcosToSelf() {
369            try {
370                return mapToSelf(ComposableFunction.ACOS);
371            } catch (FunctionEvaluationException e) {
372                throw new IllegalArgumentException(e);
373            }
374        }
375    
376        /** {@inheritDoc} */
377        public RealVector mapAsin() {
378            return copy().mapAsinToSelf();
379        }
380    
381        /** {@inheritDoc} */
382        public RealVector mapAsinToSelf() {
383            try {
384                return mapToSelf(ComposableFunction.ASIN);
385            } catch (FunctionEvaluationException e) {
386                throw new IllegalArgumentException(e);
387            }
388        }
389    
390        /** {@inheritDoc} */
391        public RealVector mapAtan() {
392            return copy().mapAtanToSelf();
393        }
394    
395        /** {@inheritDoc} */
396        public RealVector mapAtanToSelf() {
397            try {
398                return mapToSelf(ComposableFunction.ATAN);
399            } catch (FunctionEvaluationException e) {
400                throw new IllegalArgumentException(e);
401            }
402        }
403    
404        /** {@inheritDoc} */
405        public RealVector mapCbrt() {
406            return copy().mapCbrtToSelf();
407        }
408    
409        /** {@inheritDoc} */
410        public RealVector mapCbrtToSelf() {
411            try {
412                return mapToSelf(ComposableFunction.CBRT);
413            } catch (FunctionEvaluationException e) {
414                throw new IllegalArgumentException(e);
415            }
416        }
417    
418        /** {@inheritDoc} */
419        public RealVector mapCeil() {
420            return copy().mapCeilToSelf();
421        }
422    
423        /** {@inheritDoc} */
424        public RealVector mapCeilToSelf() {
425            try {
426                return mapToSelf(ComposableFunction.CEIL);
427            } catch (FunctionEvaluationException e) {
428                throw new IllegalArgumentException(e);
429            }
430        }
431    
432        /** {@inheritDoc} */
433        public RealVector mapCos() {
434            return copy().mapCosToSelf();
435        }
436    
437        /** {@inheritDoc} */
438        public RealVector mapCosToSelf() {
439            try {
440                return mapToSelf(ComposableFunction.COS);
441            } catch (FunctionEvaluationException e) {
442                throw new IllegalArgumentException(e);
443            }
444        }
445    
446        /** {@inheritDoc} */
447        public RealVector mapCosh() {
448            return copy().mapCoshToSelf();
449        }
450    
451        /** {@inheritDoc} */
452        public RealVector mapCoshToSelf() {
453            try {
454                return mapToSelf(ComposableFunction.COSH);
455            } catch (FunctionEvaluationException e) {
456                throw new IllegalArgumentException(e);
457            }
458        }
459    
460        /** {@inheritDoc} */
461        public RealVector mapDivide(double d) {
462            return copy().mapDivideToSelf(d);
463        }
464    
465        /** {@inheritDoc} */
466        public RealVector mapDivideToSelf(double d){
467            try {
468                return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d));
469            } catch (FunctionEvaluationException e) {
470                throw new IllegalArgumentException(e);
471            }
472        }
473    
474        /** {@inheritDoc} */
475        public RealVector mapExp() {
476            return copy().mapExpToSelf();
477        }
478    
479        /** {@inheritDoc} */
480        public RealVector mapExpToSelf() {
481            try {
482                return mapToSelf(ComposableFunction.EXP);
483            } catch (FunctionEvaluationException e) {
484                throw new IllegalArgumentException(e);
485            }
486        }
487    
488        /** {@inheritDoc} */
489        public RealVector mapExpm1() {
490            return copy().mapExpm1ToSelf();
491        }
492    
493        /** {@inheritDoc} */
494        public RealVector mapExpm1ToSelf() {
495            try {
496                return mapToSelf(ComposableFunction.EXPM1);
497            } catch (FunctionEvaluationException e) {
498                throw new IllegalArgumentException(e);
499            }
500        }
501    
502        /** {@inheritDoc} */
503        public RealVector mapFloor() {
504            return copy().mapFloorToSelf();
505        }
506    
507        /** {@inheritDoc} */
508        public RealVector mapFloorToSelf() {
509            try {
510                return mapToSelf(ComposableFunction.FLOOR);
511            } catch (FunctionEvaluationException e) {
512                throw new IllegalArgumentException(e);
513            }
514        }
515    
516        /** {@inheritDoc} */
517        public RealVector mapInv() {
518            return copy().mapInvToSelf();
519        }
520    
521        /** {@inheritDoc} */
522        public RealVector mapInvToSelf() {
523            try {
524                return mapToSelf(ComposableFunction.INVERT);
525            } catch (FunctionEvaluationException e) {
526                throw new IllegalArgumentException(e);
527            }
528        }
529    
530        /** {@inheritDoc} */
531        public RealVector mapLog() {
532            return copy().mapLogToSelf();
533        }
534    
535        /** {@inheritDoc} */
536        public RealVector mapLogToSelf() {
537            try {
538                return mapToSelf(ComposableFunction.LOG);
539            } catch (FunctionEvaluationException e) {
540                throw new IllegalArgumentException(e);
541            }
542        }
543    
544        /** {@inheritDoc} */
545        public RealVector mapLog10() {
546            return copy().mapLog10ToSelf();
547        }
548    
549        /** {@inheritDoc} */
550        public RealVector mapLog10ToSelf() {
551            try {
552                return mapToSelf(ComposableFunction.LOG10);
553            } catch (FunctionEvaluationException e) {
554                throw new IllegalArgumentException(e);
555            }
556        }
557    
558        /** {@inheritDoc} */
559        public RealVector mapLog1p() {
560            return copy().mapLog1pToSelf();
561        }
562    
563        /** {@inheritDoc} */
564        public RealVector mapLog1pToSelf() {
565            try {
566                return mapToSelf(ComposableFunction.LOG1P);
567            } catch (FunctionEvaluationException e) {
568                throw new IllegalArgumentException(e);
569            }
570        }
571    
572        /** {@inheritDoc} */
573        public RealVector mapMultiply(double d) {
574            return copy().mapMultiplyToSelf(d);
575        }
576    
577        /** {@inheritDoc} */
578        public RealVector mapMultiplyToSelf(double d){
579            try {
580                return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d));
581            } catch (FunctionEvaluationException e) {
582                throw new IllegalArgumentException(e);
583            }
584        }
585    
586        /** {@inheritDoc} */
587        public RealVector mapPow(double d) {
588            return copy().mapPowToSelf(d);
589        }
590    
591        /** {@inheritDoc} */
592        public RealVector mapPowToSelf(double d){
593            try {
594                return mapToSelf(BinaryFunction.POW.fix2ndArgument(d));
595            } catch (FunctionEvaluationException e) {
596                throw new IllegalArgumentException(e);
597            }
598        }
599    
600        /** {@inheritDoc} */
601        public RealVector mapRint() {
602            return copy().mapRintToSelf();
603        }
604    
605        /** {@inheritDoc} */
606        public RealVector mapRintToSelf() {
607            try {
608                return mapToSelf(ComposableFunction.RINT);
609            } catch (FunctionEvaluationException e) {
610                throw new IllegalArgumentException(e);
611            }
612        }
613    
614        /** {@inheritDoc} */
615        public RealVector mapSignum() {
616            return copy().mapSignumToSelf();
617        }
618    
619        /** {@inheritDoc} */
620        public RealVector mapSignumToSelf() {
621            try {
622                return mapToSelf(ComposableFunction.SIGNUM);
623            } catch (FunctionEvaluationException e) {
624                throw new IllegalArgumentException(e);
625            }
626        }
627    
628        /** {@inheritDoc} */
629        public RealVector mapSin() {
630            return copy().mapSinToSelf();
631        }
632    
633        /** {@inheritDoc} */
634        public RealVector mapSinToSelf() {
635            try {
636                return mapToSelf(ComposableFunction.SIN);
637            } catch (FunctionEvaluationException e) {
638                throw new IllegalArgumentException(e);
639            }
640        }
641    
642        /** {@inheritDoc} */
643        public RealVector mapSinh() {
644            return copy().mapSinhToSelf();
645        }
646    
647        /** {@inheritDoc} */
648        public RealVector mapSinhToSelf() {
649            try {
650                return mapToSelf(ComposableFunction.SINH);
651            } catch (FunctionEvaluationException e) {
652                throw new IllegalArgumentException(e);
653            }
654        }
655    
656        /** {@inheritDoc} */
657        public RealVector mapSqrt() {
658            return copy().mapSqrtToSelf();
659        }
660    
661        /** {@inheritDoc} */
662        public RealVector mapSqrtToSelf() {
663            try {
664                return mapToSelf(ComposableFunction.SQRT);
665            } catch (FunctionEvaluationException e) {
666                throw new IllegalArgumentException(e);
667            }
668        }
669    
670        /** {@inheritDoc} */
671        public RealVector mapSubtract(double d) {
672            return copy().mapSubtractToSelf(d);
673        }
674    
675        /** {@inheritDoc} */
676        public RealVector mapSubtractToSelf(double d){
677            return mapAddToSelf(-d);
678        }
679    
680        /** {@inheritDoc} */
681        public RealVector mapTan() {
682            return copy().mapTanToSelf();
683        }
684    
685        /** {@inheritDoc} */
686        public RealVector mapTanToSelf() {
687            try {
688                return mapToSelf(ComposableFunction.TAN);
689            } catch (FunctionEvaluationException e) {
690                throw new IllegalArgumentException(e);
691            }
692        }
693    
694        /** {@inheritDoc} */
695        public RealVector mapTanh() {
696            return copy().mapTanhToSelf();
697        }
698    
699        /** {@inheritDoc} */
700        public RealVector mapTanhToSelf() {
701            try {
702                return mapToSelf(ComposableFunction.TANH);
703            } catch (FunctionEvaluationException e) {
704                throw new IllegalArgumentException(e);
705            }
706        }
707    
708        /** {@inheritDoc} */
709        public RealVector mapUlp() {
710            return copy().mapUlpToSelf();
711        }
712    
713        /** {@inheritDoc} */
714        public RealVector mapUlpToSelf() {
715            try {
716                return mapToSelf(ComposableFunction.ULP);
717            } catch (FunctionEvaluationException e) {
718                throw new IllegalArgumentException(e);
719            }
720        }
721    
722        /** {@inheritDoc} */
723        public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException {
724            RealMatrix product;
725            if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
726                product = new OpenMapRealMatrix(this.getDimension(), v.getDimension());
727            } else {
728                product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension());
729            }
730            Iterator<Entry> thisIt = sparseIterator();
731            Entry thisE = null;
732            while (thisIt.hasNext() && (thisE = thisIt.next()) != null) {
733                Iterator<Entry> otherIt = v.sparseIterator();
734                Entry otherE = null;
735                while (otherIt.hasNext() && (otherE = otherIt.next()) != null) {
736                    product.setEntry(thisE.getIndex(), otherE.getIndex(),
737                                     thisE.getValue() * otherE.getValue());
738                }
739            }
740    
741            return product;
742    
743        }
744    
745        /** {@inheritDoc} */
746        public RealMatrix outerProduct(double[] v) throws IllegalArgumentException {
747            return outerProduct(new ArrayRealVector(v, false));
748        }
749    
750        /** {@inheritDoc} */
751        public RealVector projection(double[] v) throws IllegalArgumentException {
752            return projection(new ArrayRealVector(v, false));
753        }
754    
755        /** {@inheritDoc} */
756        public void set(double value) {
757            Iterator<Entry> it = iterator();
758            Entry e = null;
759            while (it.hasNext() && (e = it.next()) != null) {
760                e.setValue(value);
761            }
762        }
763    
764        /** {@inheritDoc} */
765        public double[] toArray() {
766            int dim = getDimension();
767            double[] values = new double[dim];
768            for (int i = 0; i < dim; i++) {
769                values[i] = getEntry(i);
770            }
771            return values;
772        }
773    
774        /** {@inheritDoc} */
775        public double[] getData() {
776            return toArray();
777        }
778    
779        /** {@inheritDoc} */
780        public RealVector unitVector() {
781            RealVector copy = copy();
782            copy.unitize();
783            return copy;
784        }
785    
786        /** {@inheritDoc} */
787        public void unitize() {
788            mapDivideToSelf(getNorm());
789        }
790    
791        /** {@inheritDoc} */
792        public Iterator<Entry> sparseIterator() {
793            return new SparseEntryIterator();
794        }
795    
796        /** {@inheritDoc} */
797        public Iterator<Entry> iterator() {
798            final int dim = getDimension();
799            return new Iterator<Entry>() {
800    
801                /** Current index. */
802                private int i = 0;
803    
804                /** Current entry. */
805                private EntryImpl e = new EntryImpl();
806    
807                /** {@inheritDoc} */
808                public boolean hasNext() {
809                    return i < dim;
810                }
811    
812                /** {@inheritDoc} */
813                public Entry next() {
814                    e.setIndex(i++);
815                    return e;
816                }
817    
818                /** {@inheritDoc} */
819                public void remove() {
820                    throw new MathUnsupportedOperationException();
821                }
822            };
823        }
824    
825        /** {@inheritDoc} */
826        public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException {
827            return copy().mapToSelf(function);
828        }
829    
830        /** {@inheritDoc} */
831        public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException {
832            Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator();
833            Entry e;
834            while (it.hasNext() && (e = it.next()) != null) {
835                e.setValue(function.value(e.getValue()));
836            }
837            return this;
838        }
839    
840        /** An entry in the vector. */
841        protected class EntryImpl extends Entry {
842    
843            /** Simple constructor. */
844            public EntryImpl() {
845                setIndex(0);
846            }
847    
848            /** {@inheritDoc} */
849            @Override
850            public double getValue() {
851                return getEntry(getIndex());
852            }
853    
854            /** {@inheritDoc} */
855            @Override
856            public void setValue(double newValue) {
857                setEntry(getIndex(), newValue);
858            }
859        }
860    
861        /**
862         * This class should rare be used, but is here to provide
863         * a default implementation of sparseIterator(), which is implemented
864         * by walking over the entries, skipping those whose values are the default one.
865         *
866         * Concrete subclasses which are SparseVector implementations should
867         * make their own sparse iterator, not use this one.
868         *
869         * This implementation might be useful for ArrayRealVector, when expensive
870         * operations which preserve the default value are to be done on the entries,
871         * and the fraction of non-default values is small (i.e. someone took a
872         * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
873         */
874        protected class SparseEntryIterator implements Iterator<Entry> {
875    
876            /** Dimension of the vector. */
877            private final int dim;
878    
879            /** last entry returned by {@link #next()} */
880            private EntryImpl current;
881    
882            /** Next entry for {@link #next()} to return. */
883            private EntryImpl next;
884    
885            /** Simple constructor. */
886            protected SparseEntryIterator() {
887                dim = getDimension();
888                current = new EntryImpl();
889                next = new EntryImpl();
890                if (next.getValue() == 0) {
891                    advance(next);
892                }
893            }
894    
895            /** Advance an entry up to the next nonzero one.
896             * @param e entry to advance
897             */
898            protected void advance(EntryImpl e) {
899                if (e == null) {
900                    return;
901                }
902                do {
903                    e.setIndex(e.getIndex() + 1);
904                } while (e.getIndex() < dim && e.getValue() == 0);
905                if (e.getIndex() >= dim) {
906                    e.setIndex(-1);
907                }
908            }
909    
910            /** {@inheritDoc} */
911            public boolean hasNext() {
912                return next.getIndex() >= 0;
913            }
914    
915            /** {@inheritDoc} */
916            public Entry next() {
917                int index = next.getIndex();
918                if (index < 0) {
919                    throw new NoSuchElementException();
920                }
921                current.setIndex(index);
922                advance(next);
923                return current;
924            }
925    
926            /** {@inheritDoc} */
927            public void remove() {
928                throw new MathUnsupportedOperationException();
929            }
930        }
931    
932    }