Fix a problem with the default sparseIterator when an array has exactly one non-zero element

Submitted by: Albert Huang (with some style tweeks)
Issue: MATH-367


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@942638 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
William Barker 2010-05-10 01:11:35 +00:00
parent 252aab4b18
commit 3a15d8cef2
3 changed files with 24 additions and 29 deletions

View File

@ -18,6 +18,7 @@
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.MathRuntimeException;
@ -875,34 +876,23 @@ public abstract class AbstractRealVector implements RealVector {
/** Dimension of the vector. */
private final int dim;
/** Temporary entry (reused on each call to {@link #next()}. */
private EntryImpl tmp = new EntryImpl();
/** Current entry. */
/** last entry returned by {@link #next()} */
private EntryImpl current;
/** Next entry. */
/** Next entry for {@link #next()} to return. */
private EntryImpl next;
/** Simple constructor. */
protected SparseEntryIterator() {
dim = getDimension();
current = new EntryImpl();
if (current.getValue() == 0) {
advance(current);
}
if(current.getIndex() >= 0){
// There is at least one non-zero entry
next = new EntryImpl();
next.setIndex(current.getIndex());
advance(next);
} else {
// The vector consists of only zero entries, so deny having a next
current = null;
next = new EntryImpl();
if(next.getValue() == 0){
advance(next);
}
}
/** Advance an entry up to the next non null one.
/** Advance an entry up to the next nonzero one.
* @param e entry to advance
*/
protected void advance(EntryImpl e) {
@ -919,22 +909,18 @@ public abstract class AbstractRealVector implements RealVector {
/** {@inheritDoc} */
public boolean hasNext() {
return current != null;
return next.getIndex() >= 0;
}
/** {@inheritDoc} */
public Entry next() {
tmp.setIndex(current.getIndex());
if (next != null) {
current.setIndex(next.getIndex());
advance(next);
if (next.getIndex() < 0) {
next = null;
}
} else {
current = null;
}
return tmp;
int index = next.getIndex();
if(index < 0){
throw new NoSuchElementException();
}
current.setIndex(index);
advance(next);
return current;
}
/** {@inheritDoc} */

View File

@ -58,6 +58,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="billbarker" type="fix" issue="MATH-368">
Fix spelling of getSparcity [sic] method of OpenMapRealVector
</action>
<action dev="billbarker" type="fix" issue="MATH-367" due-to="Albert Huang">
Fix problem with the default sparseIterator when a RealVector has exactly one non-zero entry
</action>
</release>
<release version="2.1" date="2010-04-02" description="
This is primarily a maintenance release, but it also includes new features and enhancements.

View File

@ -209,6 +209,12 @@ public class AbstractRealVectorTest extends TestCase {
for(Iterator<Entry> it = v.sparseIterator(); it.hasNext() && (e = it.next()) != null; i++) {
assertEquals(nonDefaultV2[i], e.getValue());
}
double [] onlyOne = {0d, 1.0, 0d};
v = new TestVectorImpl(onlyOne);
for(Iterator<Entry> it = v.sparseIterator(); it.hasNext() && (e = it.next()) != null; ) {
assertEquals(onlyOne[1], e.getValue());
}
}
public void testClone() throws Exception {