// return the matrix-vector product b = Ax public SparseVector times(SparseVector x) { SparseRowMatrix A = this; if (N != x.size()) throw new RuntimeException("Dimensions disagree"); SparseVector b = new SparseVector(N); for (int i = 0; i < N; i++) b.put(i, A.rows[i].dot(x)); return b; }
/** prune all values whose magnitude is below threshold */ public void prune(double threshold) { // for (SparseVector v : this) { for (int i = 0; i < size(); i++) { SparseVector a = get(i); a.prune(threshold); } }
/** * immutable multiply this times the vector: A * x, i.e., rowwise. * * @param v * @return */ public SparseVector times(SparseVector v) { SparseVector w = new SparseVector(); for (int i = 0; i < size(); i++) { w.add(i, get(i).times(v)); } return w; }
/** * normalise rows to rowsum * * @param rowsum for each row * @return vector of old row sums */ public SparseVector normalise(double rowsum) { SparseVector sums = new SparseVector(); int i = 0; for (SparseVector vec : this) { sums.put(i, vec.normalise(rowsum)); i++; } return sums; }
/** * get a column of the sparse matrix (expensive). * * @return */ public SparseVector getColum(int i) { SparseVector s = new SparseVector(); for (int row = 0; row < size(); row++) { double v = get(row, i); if (v != 0.) { s.put(row, v); } } return s; }
public final void plusEqualsSparse(SparseVector v) { if (indices.length == 0) return; if (index2location == null) setIndex2Location(); for (int i = 0; i < v.numLocations(); i++) { int index = v.indexAtLocation(i); if (index >= index2location.length) break; int location = index2location[index]; if (location >= 0) values[location] += v.valueAtLocation(i); } }
/** * get a row sparse vector of a matrix * * @param row row id * @return a sparse vector of {index, value} */ public SparseVector row(int row) { SparseVector sv = new SparseVector(numColumns); for (int j = rowPtr[row]; j < rowPtr[row + 1]; j++) { int col = colInd[j]; double val = get(row, col); if (val != 0.0) sv.set(col, val); } return sv; }
// sucks, but so does the visitor pattern. not often used. public void plusEquals(ConstantMatrix m, double factor) { if (m instanceof SparseVector) { values.plusEqualsSparse((SparseVector) m, factor); } else if (m instanceof SparseMatrixn) { SparseMatrixn smn = (SparseMatrixn) m; if (Arrays.equals(sizes, smn.sizes)) { values.plusEqualsSparse(smn.values, factor); } else { throw new UnsupportedOperationException("sizes of " + m + " do not match " + this); } } else { throw new UnsupportedOperationException("Can't add " + m + " to " + this); } }
/** * Unit test checking that the sparse vector does not end up ever using more than "size" elements. */ @Test public void testOverAllocation() { for (int d = 0; d < 10; d++) { SparseVector v = new SparseVector(d, 0); assertEquals(0, v.index.length); assertEquals(0, v.data.length); // Fill with non-zero elements. for (int i = 0; i < d; i++) { v.set(i, 1.0 + i); } assertEquals(d, v.index.length); assertEquals(d, v.data.length); } }
@Test public void testBug27() { double[] tfVector = {0.0, 0.5, 0.0, 0.4, 0.0}; DenseVector dense = new DenseVector(tfVector, false); SparseVector vectorTF = new SparseVector(dense); vectorTF.compact(); assertTrue(vectorTF.getUsed() == 2); // vectorTF.getUsed() returns 5 for (Iterator<VectorEntry> it = vectorTF.iterator(); it.hasNext(); ) { VectorEntry ve = it.next(); int index = ve.index(); double value = ve.get(); assertTrue(tfVector[index] == value); } }
@Override public Vector slice(int from, int to) { SparseVector res = new SparseVector(); int fi = find(from); if (fi < 0) { fi = -fi - 1; } int ti = find(to); if (ti < 0) { ti = -ti - 1; } for (int idx = fi; idx < ti; idx++) { res.set(index(idx) - from, value(idx)); } return res; }
public final double dotProduct(SparseVector v) { if (indices.length == 0) return 0; if (index2location == null) setIndex2Location(); double ret = 0; int vNumLocs = v.numLocations(); if (isBinary()) { // this vector is binary for (int i = 0; i < vNumLocs; i++) { int index = v.indexAtLocation(i); if (index >= index2location.length) break; if (index2location[index] >= 0) ret += v.valueAtLocation(i); } } else if (v.isBinary()) { // the other vector is binary for (int i = 0; i < vNumLocs; i++) { int index = v.indexAtLocation(i); if (index >= index2location.length) break; int location = index2location[index]; if (location >= 0) ret += values[location]; } } else { for (int i = 0; i < vNumLocs; i++) { int index = v.indexAtLocation(i); if (index >= index2location.length) break; int location = index2location[index]; if (location >= 0) ret += values[location] * v.valueAtLocation(i); } } return ret; }
/** * get a col sparse vector of a matrix * * @param col col id * @return a sparse vector of {index, value} */ public SparseVector column(int col) { SparseVector sv = new SparseVector(numRows); if (isCCSUsed) { for (int j = colPtr[col]; j < colPtr[col + 1]; j++) { int row = rowInd[j]; double val = get(row, col); if (val != 0.0) sv.set(row, val); } } else { for (int row = 0; row < numRows; row++) { double val = get(row, col); if (val != 0.0) sv.set(row, val); } } return sv; }
public boolean equals(Object o) { if (o instanceof SparseMatrixn) { /* This could be extended to work for all Matrixes. */ SparseMatrixn m2 = (SparseMatrixn) o; return (numDimensions == m2.numDimensions) && (sizes.equals(m2.sizes)) && (values.equals(m2.values)); } else { return false; } }
@Test public void testSparseVectorIndices() { /* * MTJ subtlety in getIndex() for SparseVector. before calling * getIndex(), you must call compact()... implementations may choose to * do nothing in this call, but the Intel extended LAPACK * implementations (and MTJ's SparseVector) require it. An alternative * to vector.getIndex() is VectorMethods.getIndex(Vector) which will * wrap this for you. It can take an arbitrary Vector and if it can be * cast to a SparseVector will compact it and use its getIndex() method * instead. (just so you're aware of this). Sam. */ // check that "infinite dimensions" doesn't use infinite memory SparseVector vector = new SparseVector(Integer.MAX_VALUE); int[] index = vector.getIndex(); assert index != null; assert index.length == 0; // check that creating with double[] with zeros works double[] entries = new double[5]; entries[0] = 0.0; entries[1] = 0.0; entries[2] = 1.0; entries[3] = 0.0; entries[4] = 2.0; Vector dense = new DenseVector(entries, false); vector = new SparseVector(dense); // NOTE: must compact before calling getIndex()!!! // vector.compact(); index = vector.getIndex(); assert index != null; assert index.length == 5 : "expected length of 5, but got " + index.length + ", with elements " + Arrays.toString(index); }
/** * Standardize the matrix entries by row- or column-wise z-scores (z=(x-u)/sigma) * * @param isByRow standardize by row if true; otherwise by column */ public void standardize(boolean isByRow) { int iters = isByRow ? numRows : numColumns; for (int iter = 0; iter < iters; iter++) { SparseVector vec = isByRow ? row(iter) : column(iter); if (vec.getCount() > 0) { double[] data = vec.getData(); double mu = Stats.mean(data); double sigma = Stats.sd(data, mu); for (VectorEntry ve : vec) { int idx = ve.index(); double val = ve.get(); double z = (val - mu) / sigma; if (isByRow) this.set(iter, idx, z); else this.set(idx, iter, z); } } } }
@Override public Vector transMultAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.transMultAdd(alpha, x, y); checkTransMultAdd(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y).getData(); // y = 1/alpha * y y.scale(1. / alpha); // y = A'x + y for (int i = 0; i < numRows; ++i) { SparseVector v = rowD[i]; int[] index = v.getIndex(); double[] data = v.getData(); int length = v.getUsed(); for (int j = 0; j < length; ++j) yd[index[j]] += data[j] * xd[i]; } // y = alpha*y = alpha * A'x + y return y.scale(alpha); }
/** * immutable multiply the vector times this: x' * A, i.e., colwise. * * @param v * @return */ public SparseVector vectorTimes(SparseVector v) { SparseVector w = new SparseVector(); // only the rows in A that v is nonzero for (int i : v.keySet()) { SparseVector a = get(i).copy(); a.factor(v.get(i)); w.add(a); } return w; }
@Test public void testGetRawData() { SparseVector vector = new SparseVector(Integer.MAX_VALUE); double[] data = vector.getRawData(); assertTrue(data != null); assertTrue(data.length == 0); assertSame(data, vector.data); assertEquals(data.length, vector.getRawIndex().length); vector.set(2, 1.0); vector.set(1, 0.0); vector.set(4, 2.0); data = vector.getRawData(); assertSame(data, vector.data); assertEquals(data.length, vector.getRawIndex().length); // In this case, the raw index is larger than the used, so the raw // indices have more entries than the other one. assertTrue(data.length > vector.getUsed()); assertTrue(data.length > vector.getIndex().length); }
public static Example readExample(BufferedReader in) throws IOException { String line = readLineSkip(in); if (line == null) { return null; } line = line.trim(); String rec = line.split("\\s")[0]; int label = Integer.parseInt(rec); String vector = ""; if (line.length() > rec.length()) { vector = line.substring(rec.length() + 1); } SparseVector sv = SparseVector.load(vector); return new Example(label, sv); }
/** * copy contructor * * @param matrix */ public SparseMatrix(SparseMatrix matrix) { for (SparseVector s : matrix) { add(s.copy()); } }
public void setSingleValue(int i, double value) { values.setValue(i, value); }
public void incrementSingleValue(int i, double delta) { double value = values.value(i); values.setValue(i, value + delta); }
/** normalise by major dimension (rows) */ public void normaliseRows() { for (SparseVector vec : this) { vec.normalise(); } }
public void setAll(double v) { values.setAll(v); }
public void timesEquals(double factor) { values.timesEquals(factor); }
/** * set the sparse vector at index i. * * @param i * @param x * @return the old value of the element */ public SparseVector set(int i, SparseVector x) { adjustMaxIndex(i, x.getLength() - 1); return super.set(i, x); }
public void divideEquals(double factor) { values.timesEquals(1 / factor); }
public double absNormalize() { double norm = values.absNorm(); values.timesEquals(1 / norm); return norm; }
public double infinityNormalize() { double norm = values.infinityNorm(); values.timesEquals(1 / norm); return norm; }