/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.math.linear;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.MathUnsupportedOperationException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.analysis.BinaryFunction;
import org.apache.commons.math.analysis.ComposableFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.FastMath;

/**
 * This class provides default basic implementations for many methods in the
 * {@link RealVector} interface.
 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
 * @since 2.1
 */
public abstract class AbstractRealVector implements RealVector {

    /**
     * Check if instance and specified vectors have the same dimension.
     * @param v vector to compare instance with
     * @exception DimensionMismatchException if the vectors do not
     * have the same dimension
     */
    protected void checkVectorDimensions(RealVector v) {
        checkVectorDimensions(v.getDimension());
    }

    /**
     * Check if instance dimension is equal to some expected value.
     *
     * @param n expected dimension.
     * @exception DimensionMismatchException if the dimension is
     * inconsistent with vector size
     */
    protected void checkVectorDimensions(int n)
        throws DimensionMismatchException {
        int d = getDimension();
        if (d != n) {
            throw new DimensionMismatchException(d, n);
        }
    }

    /**
     * Check if an index is valid.
     * @param index index to check
     * @exception MatrixIndexException if index is not valid
     */
    protected void checkIndex(final int index)
        throws MatrixIndexException {
        if (index < 0 || index >= getDimension()) {
            throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE,
                                           index, 0, getDimension() - 1);
        }
    }

    /** {@inheritDoc} */
    public void setSubVector(int index, RealVector v) throws MatrixIndexException {
        checkIndex(index);
        checkIndex(index + v.getDimension() - 1);
        setSubVector(index, v.getData());
    }

    /** {@inheritDoc} */
    public void setSubVector(int index, double[] v) throws MatrixIndexException {
        checkIndex(index);
        checkIndex(index + v.length - 1);
        for (int i = 0; i < v.length; i++) {
            setEntry(i + index, v[i]);
        }
    }

    /** {@inheritDoc} */
    public RealVector add(double[] v) throws IllegalArgumentException {
        double[] result = v.clone();
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            result[e.getIndex()] += e.getValue();
        }
        return new ArrayRealVector(result, false);
    }

    /** {@inheritDoc} */
    public RealVector add(RealVector v) throws IllegalArgumentException {
        if (v instanceof ArrayRealVector) {
            double[] values = ((ArrayRealVector)v).getDataRef();
            return add(values);
        }
        RealVector result = v.copy();
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            final int index = e.getIndex();
            result.setEntry(index, e.getValue() + result.getEntry(index));
        }
        return result;
    }

    /** {@inheritDoc} */
    public RealVector subtract(double[] v) throws IllegalArgumentException {
        double[] result = v.clone();
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            final int index = e.getIndex();
            result[index] = e.getValue() - result[index];
        }
        return new ArrayRealVector(result, false);
    }

    /** {@inheritDoc} */
    public RealVector subtract(RealVector v) throws IllegalArgumentException {
        if (v instanceof ArrayRealVector) {
            double[] values = ((ArrayRealVector)v).getDataRef();
            return add(values);
        }
        RealVector result = v.copy();
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            final int index = e.getIndex();
            v.setEntry(index, e.getValue() - result.getEntry(index));
        }
        return result;
    }

    /** {@inheritDoc} */
    public RealVector mapAdd(double d) {
        return copy().mapAddToSelf(d);
    }

    /** {@inheritDoc} */
    public RealVector mapAddToSelf(double d) {
        if (d != 0) {
            try {
                return mapToSelf(BinaryFunction.ADD.fix1stArgument(d));
            } catch (FunctionEvaluationException e) {
                throw new IllegalArgumentException(e);
            }
        }
        return this;
    }

    /** {@inheritDoc} */
    public abstract AbstractRealVector copy();

    /** {@inheritDoc} */
    public double dotProduct(double[] v) throws IllegalArgumentException {
        return dotProduct(new ArrayRealVector(v, false));
    }

    /** {@inheritDoc} */
    public double dotProduct(RealVector v) throws IllegalArgumentException {
        checkVectorDimensions(v);
        double d = 0;
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            d += e.getValue() * v.getEntry(e.getIndex());
        }
        return d;
    }

    /** {@inheritDoc} */
    public RealVector ebeDivide(double[] v) throws IllegalArgumentException {
        return ebeDivide(new ArrayRealVector(v, false));
    }

    /** {@inheritDoc} */
    public RealVector ebeMultiply(double[] v) throws IllegalArgumentException {
        return ebeMultiply(new ArrayRealVector(v, false));
    }

    /** {@inheritDoc} */
    public double getDistance(RealVector v) throws IllegalArgumentException {
        checkVectorDimensions(v);
        double d = 0;
        Iterator<Entry> it = iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            final double diff = e.getValue() - v.getEntry(e.getIndex());
            d += diff * diff;
        }
        return FastMath.sqrt(d);
    }

    /** {@inheritDoc} */
    public double getNorm() {
        double sum = 0;
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            final double value = e.getValue();
            sum += value * value;
        }
        return FastMath.sqrt(sum);
    }

    /** {@inheritDoc} */
    public double getL1Norm() {
        double norm = 0;
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            norm += FastMath.abs(e.getValue());
        }
        return norm;
    }

    /** {@inheritDoc} */
    public double getLInfNorm() {
        double norm = 0;
        Iterator<Entry> it = sparseIterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            norm = FastMath.max(norm, FastMath.abs(e.getValue()));
        }
        return norm;
    }

    /** {@inheritDoc} */
    public double getDistance(double[] v) throws IllegalArgumentException {
        return getDistance(new ArrayRealVector(v,false));
    }

    /** {@inheritDoc} */
    public double getL1Distance(RealVector v) throws IllegalArgumentException {
        checkVectorDimensions(v);
        double d = 0;
        Iterator<Entry> it = iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
        }
        return d;
    }

    /** {@inheritDoc} */
    public double getL1Distance(double[] v) throws IllegalArgumentException {
        checkVectorDimensions(v.length);
        double d = 0;
        Iterator<Entry> it = iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            d += FastMath.abs(e.getValue() - v[e.getIndex()]);
        }
        return d;
    }

    /** {@inheritDoc} */
    public double getLInfDistance(RealVector v) throws IllegalArgumentException {
        checkVectorDimensions(v);
        double d = 0;
        Iterator<Entry> it = iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
        }
        return d;
    }

    /** {@inheritDoc} */
    public double getLInfDistance(double[] v) throws IllegalArgumentException {
        checkVectorDimensions(v.length);
        double d = 0;
        Iterator<Entry> it = iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d);
        }
        return d;
    }

    /** Get the index of the minimum entry.
     * @return index of the minimum entry or -1 if vector length is 0
     * or all entries are NaN
     */
    public int getMinIndex() {
        int minIndex    = -1;
        double minValue = Double.POSITIVE_INFINITY;
        Iterator<Entry> iterator = iterator();
        while (iterator.hasNext()) {
            final Entry entry = iterator.next();
            if (entry.getValue() <= minValue) {
                minIndex = entry.getIndex();
                minValue = entry.getValue();
            }
        }
        return minIndex;
    }

    /** Get the value of the minimum entry.
     * @return value of the minimum entry or NaN if all entries are NaN
     */
    public double getMinValue() {
        final int minIndex = getMinIndex();
        return minIndex < 0 ? Double.NaN : getEntry(minIndex);
    }

    /** Get the index of the maximum entry.
     * @return index of the maximum entry or -1 if vector length is 0
     * or all entries are NaN
     */
    public int getMaxIndex() {
        int maxIndex    = -1;
        double maxValue = Double.NEGATIVE_INFINITY;
        Iterator<Entry> iterator = iterator();
        while (iterator.hasNext()) {
            final Entry entry = iterator.next();
            if (entry.getValue() >= maxValue) {
                maxIndex = entry.getIndex();
                maxValue = entry.getValue();
            }
        }
        return maxIndex;
    }

    /** Get the value of the maximum entry.
     * @return value of the maximum entry or NaN if all entries are NaN
     */
    public double getMaxValue() {
        final int maxIndex = getMaxIndex();
        return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
    }

    /** {@inheritDoc} */
    public RealVector mapAbs() {
        return copy().mapAbsToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapAbsToSelf() {
        try {
            return mapToSelf(ComposableFunction.ABS);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapAcos() {
        return copy().mapAcosToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapAcosToSelf() {
        try {
            return mapToSelf(ComposableFunction.ACOS);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapAsin() {
        return copy().mapAsinToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapAsinToSelf() {
        try {
            return mapToSelf(ComposableFunction.ASIN);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapAtan() {
        return copy().mapAtanToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapAtanToSelf() {
        try {
            return mapToSelf(ComposableFunction.ATAN);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapCbrt() {
        return copy().mapCbrtToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapCbrtToSelf() {
        try {
            return mapToSelf(ComposableFunction.CBRT);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapCeil() {
        return copy().mapCeilToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapCeilToSelf() {
        try {
            return mapToSelf(ComposableFunction.CEIL);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapCos() {
        return copy().mapCosToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapCosToSelf() {
        try {
            return mapToSelf(ComposableFunction.COS);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapCosh() {
        return copy().mapCoshToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapCoshToSelf() {
        try {
            return mapToSelf(ComposableFunction.COSH);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapDivide(double d) {
        return copy().mapDivideToSelf(d);
    }

    /** {@inheritDoc} */
    public RealVector mapDivideToSelf(double d){
        try {
            return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d));
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapExp() {
        return copy().mapExpToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapExpToSelf() {
        try {
            return mapToSelf(ComposableFunction.EXP);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapExpm1() {
        return copy().mapExpm1ToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapExpm1ToSelf() {
        try {
            return mapToSelf(ComposableFunction.EXPM1);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapFloor() {
        return copy().mapFloorToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapFloorToSelf() {
        try {
            return mapToSelf(ComposableFunction.FLOOR);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapInv() {
        return copy().mapInvToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapInvToSelf() {
        try {
            return mapToSelf(ComposableFunction.INVERT);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapLog() {
        return copy().mapLogToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapLogToSelf() {
        try {
            return mapToSelf(ComposableFunction.LOG);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapLog10() {
        return copy().mapLog10ToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapLog10ToSelf() {
        try {
            return mapToSelf(ComposableFunction.LOG10);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapLog1p() {
        return copy().mapLog1pToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapLog1pToSelf() {
        try {
            return mapToSelf(ComposableFunction.LOG1P);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapMultiply(double d) {
        return copy().mapMultiplyToSelf(d);
    }

    /** {@inheritDoc} */
    public RealVector mapMultiplyToSelf(double d){
        try {
            return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d));
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapPow(double d) {
        return copy().mapPowToSelf(d);
    }

    /** {@inheritDoc} */
    public RealVector mapPowToSelf(double d){
        try {
            return mapToSelf(BinaryFunction.POW.fix2ndArgument(d));
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapRint() {
        return copy().mapRintToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapRintToSelf() {
        try {
            return mapToSelf(ComposableFunction.RINT);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapSignum() {
        return copy().mapSignumToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapSignumToSelf() {
        try {
            return mapToSelf(ComposableFunction.SIGNUM);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapSin() {
        return copy().mapSinToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapSinToSelf() {
        try {
            return mapToSelf(ComposableFunction.SIN);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapSinh() {
        return copy().mapSinhToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapSinhToSelf() {
        try {
            return mapToSelf(ComposableFunction.SINH);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapSqrt() {
        return copy().mapSqrtToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapSqrtToSelf() {
        try {
            return mapToSelf(ComposableFunction.SQRT);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapSubtract(double d) {
        return copy().mapSubtractToSelf(d);
    }

    /** {@inheritDoc} */
    public RealVector mapSubtractToSelf(double d){
        return mapAddToSelf(-d);
    }

    /** {@inheritDoc} */
    public RealVector mapTan() {
        return copy().mapTanToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapTanToSelf() {
        try {
            return mapToSelf(ComposableFunction.TAN);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapTanh() {
        return copy().mapTanhToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapTanhToSelf() {
        try {
            return mapToSelf(ComposableFunction.TANH);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealVector mapUlp() {
        return copy().mapUlpToSelf();
    }

    /** {@inheritDoc} */
    public RealVector mapUlpToSelf() {
        try {
            return mapToSelf(ComposableFunction.ULP);
        } catch (FunctionEvaluationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /** {@inheritDoc} */
    public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException {
        RealMatrix product;
        if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
            product = new OpenMapRealMatrix(this.getDimension(), v.getDimension());
        } else {
            product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension());
        }
        Iterator<Entry> thisIt = sparseIterator();
        Entry thisE = null;
        while (thisIt.hasNext() && (thisE = thisIt.next()) != null) {
            Iterator<Entry> otherIt = v.sparseIterator();
            Entry otherE = null;
            while (otherIt.hasNext() && (otherE = otherIt.next()) != null) {
                product.setEntry(thisE.getIndex(), otherE.getIndex(),
                                 thisE.getValue() * otherE.getValue());
            }
        }

        return product;

    }

    /** {@inheritDoc} */
    public RealMatrix outerProduct(double[] v) throws IllegalArgumentException {
        return outerProduct(new ArrayRealVector(v, false));
    }

    /** {@inheritDoc} */
    public RealVector projection(double[] v) throws IllegalArgumentException {
        return projection(new ArrayRealVector(v, false));
    }

    /** {@inheritDoc} */
    public void set(double value) {
        Iterator<Entry> it = iterator();
        Entry e = null;
        while (it.hasNext() && (e = it.next()) != null) {
            e.setValue(value);
        }
    }

    /** {@inheritDoc} */
    public double[] toArray() {
        int dim = getDimension();
        double[] values = new double[dim];
        for (int i = 0; i < dim; i++) {
            values[i] = getEntry(i);
        }
        return values;
    }

    /** {@inheritDoc} */
    public double[] getData() {
        return toArray();
    }

    /** {@inheritDoc} */
    public RealVector unitVector() {
        RealVector copy = copy();
        copy.unitize();
        return copy;
    }

    /** {@inheritDoc} */
    public void unitize() {
        mapDivideToSelf(getNorm());
    }

    /** {@inheritDoc} */
    public Iterator<Entry> sparseIterator() {
        return new SparseEntryIterator();
    }

    /** {@inheritDoc} */
    public Iterator<Entry> iterator() {
        final int dim = getDimension();
        return new Iterator<Entry>() {

            /** Current index. */
            private int i = 0;

            /** Current entry. */
            private EntryImpl e = new EntryImpl();

            /** {@inheritDoc} */
            public boolean hasNext() {
                return i < dim;
            }

            /** {@inheritDoc} */
            public Entry next() {
                e.setIndex(i++);
                return e;
            }

            /** {@inheritDoc} */
            public void remove() {
                throw new MathUnsupportedOperationException();
            }
        };
    }

    /** {@inheritDoc} */
    public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException {
        return copy().mapToSelf(function);
    }

    /** {@inheritDoc} */
    public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException {
        Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator();
        Entry e;
        while (it.hasNext() && (e = it.next()) != null) {
            e.setValue(function.value(e.getValue()));
        }
        return this;
    }

    /** An entry in the vector. */
    protected class EntryImpl extends Entry {

        /** Simple constructor. */
        public EntryImpl() {
            setIndex(0);
        }

        /** {@inheritDoc} */
        @Override
        public double getValue() {
            return getEntry(getIndex());
        }

        /** {@inheritDoc} */
        @Override
        public void setValue(double newValue) {
            setEntry(getIndex(), newValue);
        }
    }

    /**
     * This class should rare be used, but is here to provide
     * a default implementation of sparseIterator(), which is implemented
     * by walking over the entries, skipping those whose values are the default one.
     *
     * Concrete subclasses which are SparseVector implementations should
     * make their own sparse iterator, not use this one.
     *
     * This implementation might be useful for ArrayRealVector, when expensive
     * operations which preserve the default value are to be done on the entries,
     * and the fraction of non-default values is small (i.e. someone took a
     * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
     */
    protected class SparseEntryIterator implements Iterator<Entry> {

        /** Dimension of the vector. */
        private final int dim;

        /** last entry returned by {@link #next()} */
        private EntryImpl current;

        /** Next entry for {@link #next()} to return. */
        private EntryImpl next;

        /** Simple constructor. */
        protected SparseEntryIterator() {
            dim = getDimension();
            current = new EntryImpl();
            next = new EntryImpl();
            if (next.getValue() == 0) {
                advance(next);
            }
        }

        /** Advance an entry up to the next nonzero one.
         * @param e entry to advance
         */
        protected void advance(EntryImpl e) {
            if (e == null) {
                return;
            }
            do {
                e.setIndex(e.getIndex() + 1);
            } while (e.getIndex() < dim && e.getValue() == 0);
            if (e.getIndex() >= dim) {
                e.setIndex(-1);
            }
        }

        /** {@inheritDoc} */
        public boolean hasNext() {
            return next.getIndex() >= 0;
        }

        /** {@inheritDoc} */
        public Entry next() {
            int index = next.getIndex();
            if (index < 0) {
                throw new NoSuchElementException();
            }
            current.setIndex(index);
            advance(next);
            return current;
        }

        /** {@inheritDoc} */
        public void remove() {
            throw new MathUnsupportedOperationException();
        }
    }

}
