shh.csparse
Class SparseV

Object
  extended byAbstractCollection
      extended byAbstractList
          extended byArrayList
              extended bySparseV
All Implemented Interfaces:
Cloneable, Collection, List, RandomAccess, Serializable

public class SparseV
extends ArrayList
implements Cloneable

A SparseV is a list of SparseElts representing a vector over the integral domain that underlies the SparseElts. The SparseElts must have distinct non-negative indices and be sorted in order of increasing index. A SparseElt with zero value will (and must) never appear in a SparseV.

To save space, a SparseV doesn't store its own dimension. That is, it doesn't know how many zeros it has after the last non-zero entry. We expect the caller will keep track of the dimension.

It's possible to confuse "index in the sparse vector" with index in the sense of List. For instance, if this = {{1,17}, {3,2197}}, then this.get(1) is the SparseElt of value 2197, while this.getElt(1) is the SparseElt of value 17. The methods defined within this class, like getElt, use "index in the sparse vector" exclusively. The protected methods getListIndex(...) transform "index in the sparse vector" to List index, though the user should never have to call these directly.

Most linear algebra operations on a SparseV are destructive. In order to save space, they overwrite the vector's entries. To do things non-destructively, operate on a copy made by ArrayList.clone().

This package treats a null SparseV as the zero vector. Functions that return SparseElts may return null to stand for a SparseElt of value 0.

As with all subclasses of List, the AbstractList.equals(java.lang.Object) method tests whether the elements are equal term by term.

Author:
Mark McConnell
See Also:
Serialized Form

Field Summary
 
Fields inherited from class AbstractList
modCount
 
Constructor Summary
SparseV()
          Constructs a zero vector.
 
Method Summary
 void add(SparseV b)
          Overwrites this with its sum with b.
 void alter(int i1, SparseElt factor, int i2)
          Alters the entry with index i1 by adding to it (the value in factor) times (the entry with index i2).
 void alter(SparseElt factor, SparseV b)
          Alters this by adding to it (the value in factor) times b.
 SparseElt dot(SparseV b)
          Returns a SparseElt with unspecified index and value equal to the dot product of this and b.
 SparseElt getElt(int i)
          Returns the element with index i in the sparse vector, or null if there isn't one.
 SparseElt getFirstFrom(int i)
          Returns the non-zero entry whose index in the sparse vector has the smallest possible value ≥ i.
 int getLastIndex()
          Returns the largest index of a non-zero entry, or -1 for a zero vector.
protected  int getListIndex(int i)
          Same as getListIndex(i, 0).
protected  int getListIndex(int i, int start)
          Best explained by examples.
protected  int getListIndex(SparseElt e)
          Same as getListIndex(int) for e's index.
 double getNormSq()
          If every entry has a norm-squared z zbar (for example, if the underlying ring is Z or any subring of C), then this method returns the norm-squared of the vector.
 int getNumFrom(int i)
          Returns the number of non-zero entries whose index in the sparse vector is ≥ i.
 boolean isZero()
          Whether this is the zero vector.
 void negate()
          Overwrites this with its scalar product by -1.
 void negateElt(int i)
          Replaces the entry of index i with its negative.
static void printLineByLine(SparseV v, int m, PrintStream stream)
          Prints v to stream as a dense vector of length m, one entry per line.
 void scalarMult(SparseElt s)
          Overwrites this with its scalar product by the value stored in s.
 void setElt(SparseElt s)
          Sets the entry with s's index to s.
 void swap(int i, int j)
          Interchanges the i-th and j-th entries; it's required that i < j.
 void updateNormSq()
          You must call this before using getNormSq(), and call it again if any operation changes the values of this vector.
 
Methods inherited from class ArrayList
add, add, addAll, addAll, clear, clone, contains, ensureCapacity, get, indexOf, isEmpty, lastIndexOf, remove, removeRange, set, size, toArray, toArray, trimToSize
 
Methods inherited from class AbstractList
equals, hashCode, iterator, listIterator, listIterator, subList
 
Methods inherited from class AbstractCollection
containsAll, remove, removeAll, retainAll, toString
 
Methods inherited from class Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface List
containsAll, equals, hashCode, iterator, listIterator, listIterator, remove, removeAll, retainAll, subList
 

Constructor Detail

SparseV

public SparseV()
Constructs a zero vector.

Method Detail

getListIndex

protected final int getListIndex(SparseElt e)
Same as getListIndex(int) for e's index.


getListIndex

protected final int getListIndex(int i)
Same as getListIndex(i, 0).


getListIndex

protected int getListIndex(int i,
                           int start)
Best explained by examples. Let this = {{0,17}, {3,2197}}. If i == 3, the method returns 1, because the 3rd entry of the vector is in the 1st position of the underlying ArrayList. If no SparseElt has getIndex() == i, the method returns -(insertion point)-1, as per Collections.binarySearch(List, Object, Comparator).

The above discussion assumed start == 0. In general, the search runs over the indices in the underlying ArrayList that are ≥ start.

For the sake of speed, the algorithm uses a binary search.


add

public void add(SparseV b)
Overwrites this with its sum with b. Does not alter b.


alter

public void alter(SparseElt factor,
                  SparseV b)
Alters this by adding to it (the value in factor) times b. The index in factor is ignored.

The code assumes the underlying ring has no zero divisors.


alter

public void alter(int i1,
                  SparseElt factor,
                  int i2)
Alters the entry with index i1 by adding to it (the value in factor) times (the entry with index i2). The index in factor is ignored.

The code assumes the underlying ring has no zero divisors.


scalarMult

public void scalarMult(SparseElt s)
Overwrites this with its scalar product by the value stored in s.

The code assumes the underlying ring has no zero divisors.


negate

public void negate()
Overwrites this with its scalar product by -1.


negateElt

public void negateElt(int i)
Replaces the entry of index i with its negative.


dot

public SparseElt dot(SparseV b)
Returns a SparseElt with unspecified index and value equal to the dot product of this and b.


getElt

public SparseElt getElt(int i)
Returns the element with index i in the sparse vector, or null if there isn't one.


setElt

public void setElt(SparseElt s)
Sets the entry with s's index to s.


swap

public void swap(int i,
                 int j)
Interchanges the i-th and j-th entries; it's required that i < j.


isZero

public final boolean isZero()
Whether this is the zero vector. (A null SparseV is also considered a zero vector.)


getLastIndex

public int getLastIndex()
Returns the largest index of a non-zero entry, or -1 for a zero vector.


getNumFrom

public int getNumFrom(int i)
Returns the number of non-zero entries whose index in the sparse vector is ≥ i. For instance, if this = {{1,17}, {3,2197}, {5,52}}, then getNumFrom(3) returns 2, and getNumFrom(4) and getNumFrom(5) both return 1.

See Also:
getFirstFrom(int)

getFirstFrom

public SparseElt getFirstFrom(int i)
Returns the non-zero entry whose index in the sparse vector has the smallest possible value ≥ i. Returns null if no such entry exists.

See Also:
getNumFrom(int)

getNormSq

public final double getNormSq()
If every entry has a norm-squared z zbar (for example, if the underlying ring is Z or any subring of C), then this method returns the norm-squared of the vector. If not, this method returns the size, which is the norm in the counting norm.

You must call updateNormSq() before using this method, and call it again if any operation changes the values of this vector. Because it's not always needed, the norm-squared is not updated automatically by the vector operations.


updateNormSq

public void updateNormSq()
You must call this before using getNormSq(), and call it again if any operation changes the values of this vector. Because it's not always needed, the norm-squared is not updated automatically by the vector operations.


printLineByLine

public static void printLineByLine(SparseV v,
                                   int m,
                                   PrintStream stream)
Prints v to stream as a dense vector of length m, one entry per line. Giving System.out for stream prints to standard output. It's an error if v.getLastIndex() is not < m.