diff options
Diffstat (limited to 'src/main/java/org/apache/commons/math/linear/AbstractRealVector.java')
-rw-r--r-- | src/main/java/org/apache/commons/math/linear/AbstractRealVector.java | 932 |
1 files changed, 932 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java new file mode 100644 index 0000000..e39c9ce --- /dev/null +++ b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java @@ -0,0 +1,932 @@ +/* + * 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(); + } + } + +} |