/** * Create from a Double array. * Only non-zero entries will be stored * @param values The set of values to create from * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(Double[] values, double epsilon) { virtualSize = values.length; entries = new OpenIntToDoubleHashMap(0.0); this.epsilon = epsilon; for (int key = 0; key < values.length; key++) { double value = values[key].doubleValue(); if (!isDefaultValue(value)) { entries.put(key, value); } } }
/** * Put a value associated with a key in the map. * @param key key to which value is associated * @param value value to put in the map * @return previous value associated with the key */ public double put(final int key, final double value) { int index = findInsertionIndex(key); double previous = missingEntries; boolean newMapping = true; if (index < 0) { index = changeIndexSign(index); previous = values[index]; newMapping = false; } keys[index] = key; states[index] = FULL; values[index] = value; if (newMapping) { ++size; if (shouldGrowTable()) { growTable(); } ++count; } return previous; }
/** * Build an empty map with specified size. * @param expectedSize expected number of elements in the map * @param missingEntries value to return when a missing entry is fetched */ public OpenIntToDoubleHashMap(final int expectedSize, final double missingEntries) { final int capacity = computeCapacity(expectedSize); keys = new int[capacity]; values = new double[capacity]; states = new byte[capacity]; this.missingEntries = missingEntries; mask = capacity - 1; }
/** * Remove the value associated with a key. * @param key key to which the value is associated * @return removed value */ public double remove(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return doRemove(index); } if (states[index] == FREE) { return missingEntries; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return doRemove(index); } } return missingEntries; }
final int hash = hashOf(key); int index = hash & mask; if (states[index] == FREE) { return index; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index); int perturb = perturb(hash); int j = index; if (states[index] == FULL) { while (true) { j = probe(perturb, j); index = j & mask; perturb >>= PERTURB_SHIFT; return changeIndexSign(index); j = probe(perturb, j); index = j & mask; return firstRemoved; } else if (states[index] == FULL && keys[index] == key) { return changeIndexSign(index);
for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { iterator.advance(); final double value = iterator.value(); for (int j = 0; j < outCols; ++j) { final int rightKey = m.computeKey(k, j); if (m.entries.containsKey(rightKey)) { final int outKey = out.computeKey(i, j); final double outValue = out.entries.get(outKey) + value * m.entries.get(rightKey); if (outValue == 0.0) { out.entries.remove(outKey); } else { out.entries.put(outKey, outValue);
/** {@inheritDoc} */ @Override public void multiplyEntry(int row, int column, double factor) throws MatrixIndexException { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); final int key = computeKey(row, column); final double value = entries.get(key) * factor; if (value == 0.0) { entries.remove(key); } else { entries.put(key, value); } }
/** Simple constructor. */ protected OpenMapSparseIterator() { iter = entries.iterator(); current = new OpenMapEntry(iter); }
/** * Optimized method to add two OpenMapRealVectors. Copies the larger vector, iterates over the smaller. * @param v Vector to add with * @return The sum of <code>this</code> with <code>v</code> * @throws IllegalArgumentException If the dimensions don't match */ public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{ checkVectorDimensions(v.getDimension()); boolean copyThis = entries.size() > v.entries.size(); OpenMapRealVector res = copyThis ? this.copy() : v.copy(); Iterator iter = copyThis ? v.entries.iterator() : entries.iterator(); OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries; while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (randomAccess.containsKey(key)) { res.setEntry(key, randomAccess.get(key) + iter.value()); } else { res.setEntry(key, iter.value()); } } return res; }
/** * Distance between two vectors. * <p>This method computes the distance consistent with * L<sub>1</sub> norm, i.e. the sum of the absolute values of * elements differences.</p> * @param v vector to which distance is requested * @return distance between two vectors. */ public double getL1Distance(OpenMapRealVector v) { double max = 0; Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); double delta = Math.abs(iter.value() - v.getEntry(iter.key())); max += delta; } iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (!entries.containsKey(key)) { double delta = Math.abs(iter.value()); max += Math.abs(delta); } } return max; }
/** {@inheritDoc} */ public void setEntry(int index, double value) throws MatrixIndexException { checkIndex(index); if (!isDefaultValue(value)) { entries.put(index, value); } else if (entries.containsKey(index)) { entries.remove(index); } }
/** * Optimized method to compute the dot product with an OpenMapRealVector. * Iterates over the smaller of the two. * @param v The vector to compute the dot product with * @return The dot product of <code>this</code> and <code>v</code> * @throws IllegalArgumentException If the dimensions don't match */ public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException { checkVectorDimensions(v.getDimension()); boolean thisIsSmaller = entries.size() < v.entries.size(); Iterator iter = thisIsSmaller ? entries.iterator() : v.entries.iterator(); OpenIntToDoubleHashMap larger = thisIsSmaller ? v.entries : entries; double d = 0; while(iter.hasNext()) { iter.advance(); d += iter.value() * larger.get(iter.key()); } return d; }
/** * Optimized method to subtract OpenMapRealVectors. * @param v The vector to subtract from <code>this</code> * @return The difference of <code>this</code> and <code>v</code> * @throws IllegalArgumentException If the dimensions don't match */ public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{ checkVectorDimensions(v.getDimension()); OpenMapRealVector res = copy(); Iterator iter = v.getEntries().iterator(); while (iter.hasNext()) { iter.advance(); int key = iter.key(); if (entries.containsKey(key)) { res.setEntry(key, entries.get(key) - iter.value()); } else { res.setEntry(key, -iter.value()); } } return res; }
/** * Build a vector with known the sparseness and zero tolerance setting (for advanced use only). * @param dimension The size of the vector * @param expectedSize The expected number of non-zero entries * @param epsilon The tolerance for having a value considered zero */ public OpenMapRealVector(int dimension, int expectedSize, double epsilon) { virtualSize = dimension; entries = new OpenIntToDoubleHashMap(expectedSize, 0.0); this.epsilon = epsilon; }
/** {@inheritDoc} */ @Override public void unitize() { double norm = getNorm(); if (isDefaultValue(norm)) { throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); } Iterator iter = entries.iterator(); while (iter.hasNext()) { iter.advance(); entries.put(iter.key(), iter.value() / norm); } }
/** {@inheritDoc} */ @Override public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException { checkVectorDimensions(v.length); OpenMapRealVector res = new OpenMapRealVector(this); for (int i = 0; i < v.length; i++) { if (entries.containsKey(i)) { res.setEntry(i, entries.get(i) - v[i]); } else { res.setEntry(i, -v[i]); } } return res; }
/** {@inheritDoc} */ public double getEntry(int index) throws MatrixIndexException { checkIndex(index); return entries.get(index); }
/** * Find the index at which a key should be inserted * @param key key to lookup * @return index at which key should be inserted */ private int findInsertionIndex(final int key) { return findInsertionIndex(keys, states, key, mask); }
/** * Check if a value is associated with a key. * @param key key to check * @return true if a value is associated with key */ public boolean containsKey(final int key) { final int hash = hashOf(key); int index = hash & mask; if (containsKey(key, index)) { return true; } if (states[index] == FREE) { return false; } int j = index; for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { j = probe(perturb, j); index = j & mask; if (containsKey(key, index)) { return true; } } return false; }
for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { iterator.advance(); final double value = iterator.value(); for (int j = 0; j < outCols; ++j) { final int rightKey = m.computeKey(k, j); if (m.entries.containsKey(rightKey)) { final int outKey = out.computeKey(i, j); final double outValue = out.entries.get(outKey) + value * m.entries.get(rightKey); if (outValue == 0.0) { out.entries.remove(outKey); } else { out.entries.put(outKey, outValue);