/** * Creates a new sparse vector by copying the values from another * * @param toCopy the vector to copy the values of */ public SparseVector(Vec toCopy) { this(toCopy.length(), toCopy.nnz()); for (IndexValue iv : toCopy) { indexes[used] = iv.getIndex(); values[used++] = iv.getValue(); } }
@Override public void mutableAdd(double c, Vec v) { clearCaches(); if (c == 0.0) return; if (v instanceof SparseVector) { SparseVector b = (SparseVector) v; int p1 = 0, p2 = 0; while (p1 < used && p2 < b.used) { int a1 = indexes[p1], a2 = b.indexes[p2]; if (a1 == a2) { values[p1] += c * b.values[p2]; p1++; p2++; } else if (a1 > a2) { // 0 + some value is that value, set it this.set(a2, c * b.values[p2]); /* * p2 must be increment becase were moving to the next value * * p1 must be be incremented becase a2 was less thenn the current index. * So the inseration occured before p1, so for indexes[p1] to == a1, * p1 must be incremented * */ p1++; p2++; } else // a1 < a2, thats adding 0 to this vector, nothing to do. { p1++; } } // One of them is now empty. // If b is not empty, we must add b to this. If b is empty, we would be adding zeros to this // [so we do nothing] while (p2 < b.used) this.set(b.indexes[p2], c * b.values[p2++]); // TODO Can be done more efficently } else if (v.isSparse()) { if (v.nnz() == 0) return; int p1 = 0; Iterator<IndexValue> iter = v.getNonZeroIterator(); IndexValue iv = iter.next(); while (p1 < used && iv != null) { int a1 = indexes[p1]; int a2 = iv.getIndex(); if (a1 == a2) { values[p1++] += c * iv.getValue(); if (iter.hasNext()) iv = iter.next(); else break; } else if (a1 > a2) { this.set(a2, c * iv.getValue()); p1++; if (iter.hasNext()) iv = iter.next(); else break; } else p1++; } } else { // Else it is dense for (int i = 0; i < length(); i++) this.set(i, this.get(i) + c * v.get(i)); } }