org.carrot2.mahout.math.RandomAccessSparseVector Maven / Gradle / Ivy
/*
* Carrot2 project.
*
* Copyright (C) 2002-2016, Dawid Weiss, Stanisław Osiński.
* All rights reserved.
*
* Refer to the full license file "carrot2.LICENSE"
* in the root folder of the repository checkout or at:
* http://www.carrot2.org/carrot2.LICENSE
*/
package org.carrot2.mahout.math;
import java.util.Iterator;
import org.carrot2.mahout.math.list.IntArrayList;
import org.carrot2.mahout.math.map.OpenIntDoubleHashMap;
import org.carrot2.shaded.guava.common.collect.AbstractIterator;
public class RandomAccessSparseVector extends AbstractVector {
private static final int INITIAL_CAPACITY = 11;
private OpenIntDoubleHashMap values;
public RandomAccessSparseVector() {
super(0);
}
public RandomAccessSparseVector(int cardinality) {
this(cardinality, Math.min(cardinality, INITIAL_CAPACITY)); // arbitrary estimate of 'sparseness'
}
public RandomAccessSparseVector(int cardinality, int initialCapacity) {
super(cardinality);
values = new OpenIntDoubleHashMap(initialCapacity);
}
public RandomAccessSparseVector(Vector other) {
this(other.size(), other.getNumNondefaultElements());
Iterator it = other.iterateNonZero();
Element e;
while (it.hasNext() && (e = it.next()) != null) {
values.put(e.index(), e.get());
}
}
private RandomAccessSparseVector(int cardinality, OpenIntDoubleHashMap values) {
super(cardinality);
this.values = values;
}
public RandomAccessSparseVector(RandomAccessSparseVector other, boolean shallowCopy) {
super(other.size());
values = shallowCopy ? other.values : (OpenIntDoubleHashMap)other.values.clone();
}
@Override
public RandomAccessSparseVector clone() {
return new RandomAccessSparseVector(size(), (OpenIntDoubleHashMap) values.clone());
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append('{');
Iterator it = iterateNonZero();
boolean first = true;
while (it.hasNext()) {
if (first) {
first = false;
} else {
result.append(',');
}
Element e = it.next();
result.append(e.index());
result.append(':');
result.append(e.get());
}
result.append('}');
return result.toString();
}
@Override
public Vector assign(Vector other) {
if (size() != other.size()) {
throw new CardinalityException(size(), other.size());
}
values.clear();
Iterator it = other.iterateNonZero();
Element e;
while (it.hasNext() && (e = it.next()) != null) {
setQuick(e.index(), e.get());
}
return this;
}
@Override
public boolean isDense() {
return false;
}
@Override
public boolean isSequentialAccess() {
return false;
}
@Override
public double getQuick(int index) {
return values.get(index);
}
@Override
public void setQuick(int index, double value) {
lengthSquared = -1.0;
if (value == 0.0) {
values.removeKey(index);
} else {
values.put(index, value);
}
}
@Override
public int getNumNondefaultElements() {
return values.size();
}
@Override
public RandomAccessSparseVector like() {
return new RandomAccessSparseVector(size(), values.size());
}
@Override
public Iterator iterateNonZero() {
return new NonDefaultIterator();
}
@Override
public Iterator iterator() {
return new AllIterator();
}
private final class NonDefaultIterator extends AbstractIterator {
private final RandomAccessElement element = new RandomAccessElement();
private final IntArrayList indices = new IntArrayList();
private int offset;
private NonDefaultIterator() {
values.keys(indices);
}
@Override
protected Element computeNext() {
if (offset >= indices.size()) {
return endOfData();
}
element.index = indices.get(offset);
offset++;
return element;
}
}
private final class AllIterator extends AbstractIterator {
private final RandomAccessElement element = new RandomAccessElement();
private AllIterator() {
element.index = -1;
}
@Override
protected Element computeNext() {
if (element.index + 1 < size()) {
element.index++;
return element;
} else {
return endOfData();
}
}
}
private final class RandomAccessElement implements Element {
int index;
@Override
public double get() {
return values.get(index);
}
@Override
public int index() {
return index;
}
@Override
public void set(double value) {
lengthSquared = -1;
if (value == 0.0) {
values.removeKey(index);
} else {
values.put(index, value);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy