You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mahout.apache.org by Dmitriy Lyubimov <dl...@gmail.com> on 2015/03/03 00:34:10 UTC

Bug in non-zero iterators over Sequential Access sparse vectors

it looks like assigning 0s in a view of SequentialAccessSparseVector
doesn't work, as it internally using setQuick() which tirms the length
of non-zero elements (?)
which causes invalidation of the iterator state.

in particular, this simple test fails:

val svec = new SequentialAccessSparseVector(30)

svec(1) = -0.5
svec(3) = 0.5
println(svec)

svec(1 until svec.length) ::= ( _ => 0)
println(svec)

svec.sum shouldBe 0

This produces  output

{1:-0.5,3:0.5}
{3:0.5}

The reason seems to be in the way vector view handles non-zero iterator:

public final class NonZeroIterator extends AbstractIterator<Element> {

  private final Iterator<Element> it;

  private NonZeroIterator() {
    it = vector.nonZeroes().iterator();
  }

  @Override
  protected Element computeNext() {
    while (it.hasNext()) {
      Element el = it.next();
      if (isInView(el.index()) && el.get() != 0) {
        Element decorated = vector.getElement(el.index());
        return new DecoratorElement(decorated);
      }
    }
    return endOfData();
  }

}


In particular, the problem lies in the line

        Element decorated = vector.getElement(el.index());

This creates yet another element which is AbstractVector.LocalElement
instead of iterator's element which would not cause iterator state
invalidation during assignment.

The question is why it tries to create yet another element instead of
decorating iterator's element itself in the Vector View???

I would just replace this line with simply

Element decorated = el

but i guess it might break something? what it is it might break?