/** * Construct a new vector from a key set and value array. * * @param ks The key set. Used as-is, and will be modified. Pass a clone, usually. * @param vs The value array. */ @SuppressWarnings("PMD.ArrayIsStoredDirectly") SparseVector(LongKeyDomain ks, double[] vs) { assert vs.length >= ks.domainSize(); keys = ks; keys.acquire(); values = vs; }
/** * Construct a new vector from the contents of a map. The key domain is the key set of the map. * Therefore, no new keys can be added to this vector. * * @param keyValueMap A map providing the values for the vector. */ SparseVector(Long2DoubleMap keyValueMap) { keys = LongKeyDomain.fromCollection(keyValueMap.keySet(), true); final int len = keys.domainSize(); values = new double[len]; for (int i = 0; i < len; i++) { values[i] = keyValueMap.get(keys.getKey(i)); } }
/** * Check whether an entry is set. * * @param entry The entry. * @return {@code true} if the entry is set in this vector. * @throws IllegalArgumentException if the entry is not from this vector or another vector sharing * the same key domain. Only vectors and their side channels share key domains for the * purposes of this check. */ public boolean isSet(VectorEntry entry) { final SparseVector evec = entry.getVector(); final int eind = entry.getIndex(); if (evec == null) { throw new IllegalArgumentException("entry is not associated with a vector"); } else if (!keys.isCompatibleWith(evec.keys)) { throw new IllegalArgumentException("entry does not have safe key domain"); } assert entry.getKey() == keys.getKey(eind); return keys.indexIsActive(eind); }
/** * Get the value for the entry's key. * * @param entry A {@code VectorEntry} with the key to look up * @return the key's value * @throws IllegalArgumentException if the entry is unset, or if it is not from this vector or * another vector sharing the same key domain. Only vectors and their side channels share key * domains for the purposes of this check. */ public double get(VectorEntry entry) { final SparseVector evec = entry.getVector(); final int eind = entry.getIndex(); if (evec == null) { throw new IllegalArgumentException("entry is not associated with a vector"); } else if (!evec.keys.isCompatibleWith(keys)) { throw new IllegalArgumentException("entry does not have safe key domain"); } assert entry.getKey() == keys.getKey(eind); if (keys.indexIsActive(eind)) { return values[eind]; } else { throw new IllegalArgumentException("Key " + entry.getKey() + " is not set"); } }
/** * Get the value for {@var key}. * * @param key the key to look up * @param dft The value to return if the key is not in the vector * @return the value (or {@var dft} if the key is not set to a value) */ public double get(long key, double dft) { final int idx = keys.getIndexIfActive(key); if (idx >= 0) { return values[idx]; } else { return dft; } }
/** * Get the value for {@var key}. * * @param key the key to look up; the key must be in the key set. * @return the key's value * @throws IllegalArgumentException if {@var key} is not in the key set. */ public double get(long key) { final int idx = keys.getIndexIfActive(key); if (idx >= 0) { return values[idx]; } else { throw new IllegalArgumentException("Key " + key + " is not in the key set"); } }
/** * Get the collection of values of this vector. * * @return The collection of all values in this vector. */ public DoubleCollection values() { DoubleArrayList lst = new DoubleArrayList(size()); IntIterator iter = keys.activeIndexIterator(false); while (iter.hasNext()) { int idx = iter.nextInt(); lst.add(values[idx]); } return lst; }
/** * Fast iterator over entries (it can reuse entry objects). * * @param state The state of entries to iterate. * @return a fast iterator over all key/value pairs * @see it.unimi.dsi.fastutil.longs.Long2DoubleMap.FastEntrySet#fastIterator() * Long2DoubleMap.FastEntrySet.fastIterator() * @since 0.11 */ public Iterator<VectorEntry> fastIterator(VectorEntry.State state) { IntIterator iter; switch (state) { case SET: iter = keys.activeIndexIterator(isMutable()); break; case UNSET: { iter = keys.clone().invert().activeIndexIterator(false); break; } case EITHER: { iter = IntIterators.fromTo(0, keys.domainSize()); break; } default: // should be impossible throw new IllegalArgumentException("invalid entry state"); } return new FastIterImpl(iter, state); }
/** * Construct a new sparse vector with a particular domain. Allocates the value storage. * * @param ks The key set. Used as-is, and will be modified. Pass a clone, usually. */ SparseVector(LongKeyDomain ks) { this(ks, new double[ks.domainSize()]); ks.setAllActive(false); }
/** * Get the size of this vector (the number of keys). * * @return The number of keys in the vector. This is at most the size of the key domain. */ public int size() { return keys.size(); }
/** * Get the set of unset keys. This is \(D \\ S\), where \(D\) is the key domain and \(S\) the key * set. */ public LongSortedSet unsetKeySet() { return keys.clone().invert().activeSetView(); }
/** * Get the set of keys of this vector. It is a subset of the key domain. The keys will be in * sorted order. * * @return The set of keys used in this vector. */ public LongSortedSet keySet() { return keys.activeSetView(); }
/** * Get the key domain for this vector. All keys used are in this set. The keys will be in sorted * order. * * @return The key domain for this vector. */ public LongSortedSet keyDomain() { return keys.domain(); }
/** * Query whether the vector contains an entry for the key in question. * * @param key The key to search for. * @return {@code true} if the key exists. */ public boolean containsKey(long key) { return keys.keyIsActive(key); }