mikera.vectorz.impl.GrowableIndexedVector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vectorz Show documentation
Show all versions of vectorz Show documentation
Fast double-precision vector and matrix maths library for Java, supporting N-dimensional numeric arrays.
package mikera.vectorz.impl;
import java.util.Iterator;
import mikera.indexz.GrowableIndex;
import mikera.indexz.Index;
import mikera.vectorz.AVector;
import mikera.vectorz.GrowableVector;
import mikera.vectorz.Tools;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;
/**
* Implementation for a sparse indexed vector that can accumulate index/value pairs efficiently (in order)
*
* Length grows if elements are added beyond the end of the vector
*
* @author Mike
*/
public class GrowableIndexedVector extends AVector implements ISparseVector {
private static final long serialVersionUID = 441979517032171392L;
private int length;
private final GrowableIndex index;
private final GrowableVector data;
private GrowableIndexedVector(int length, GrowableIndex index, GrowableVector data) {
this.length=length;
this.index=index;
this.data=data;
}
private GrowableIndexedVector(int length) {
this.length=length;
this.index=new GrowableIndex();
this.data=new GrowableVector();
}
private GrowableIndexedVector() {
this(0);
}
/**
* Creates a GrowableIndexedVector from the specified Iterable object
* @param iterable An Iterable containing java.lang.Number instances
* @return
*/
public static GrowableIndexedVector create(Iterable> iterable) {
GrowableIndexedVector v=new GrowableIndexedVector();
for (Object o: iterable) {
v.length++;
double d=Tools.toDouble(o);
if (d!=0.0) {
v.append(v.length-1,d);
}
}
return v;
}
/**
* Creates a GrowableIndexedVector from the specified Iterable object
* @param iterable An Iterable containing java.lang.Number instances
* @return
*/
public static GrowableIndexedVector create(AVector v) {
if (v instanceof ISparseVector) {
return create((ISparseVector) v);
}
return new GrowableIndexedVector(v.length(),GrowableIndex.wrap(v.nonZeroIndices().clone()),GrowableVector.wrap(v.nonZeroValues().clone()));
}
public static GrowableIndexedVector create(ISparseVector v) {
return new GrowableIndexedVector(v.length(),GrowableIndex.create(v.nonSparseIndex()),GrowableVector.create(v.nonSparseValues()));
}
/**
* Creates a GrowableIndexedVector from the specified Iterator object
* @param iterator An Iterator over java.lang.Number instances
* @return
*/
public static GrowableIndexedVector create(Iterator> iterator) {
GrowableIndexedVector v=new GrowableIndexedVector();
while (iterator.hasNext()) {
v.length++;
double d=Tools.toDouble(iterator.next());
if (d!=0.0) {
v.append(v.length-1,d);
}
}
return v;
}
/**
* Creates a zero-filled GrowableIndexedVector with the specified initial length
* @param len
* @return
*/
public static GrowableIndexedVector createLength(int len) {
return new GrowableIndexedVector(len);
}
@Override
public double get(int i) {
checkIndex(i);
int ix=index.indexPosition(i);
if (ix<0) return 0.0;
return data.get(ix);
}
/**
* Adds a value to this GrawableIndexedVector at the specified position.
* Grows the vector if required.
* @param i
* @param value
*/
public void append(int i, double value) {
index.checkedAppend(i);
data.append(value);
if (i>=length) length=i+1;
}
@Override
public void set(int i, double value) {
if (i<0) throw new IndexOutOfBoundsException(ErrorMessages.invalidIndex(this, i));
if (i>=length) {
append(i,value);
return;
}
int ix=index.indexPosition(i);
if (ix<0) {
int pos=index.include(i);
if (index.length()>data.length()) {
data.insert(pos,value);
} else {
data.set(pos,value);
}
} else {
data.unsafeSet(ix, value);
}
}
public void append(double v) {
set(length,v);
}
@Override
public boolean isFullyMutable() {
return true;
}
@Override
public double dotProduct(double[] data, int offset) {
return toSparseIndexedVector().dotProduct(data,offset);
}
@Override
public SparseIndexedVector toSparseIndexedVector() {
return SparseIndexedVector.wrap(length, Index.create(index), data.toDoubleArray());
}
@Override
public AVector exactClone() {
return new GrowableIndexedVector(length,index.exactClone(), data.exactClone());
}
@Override
public SparseIndexedVector sparseClone() {
return toSparseIndexedVector();
}
@Override
public SparseIndexedVector sparse() {
// we do this to ensure a "full" implementation is used
return toSparseIndexedVector();
}
public int nonSparseElementCount() {
return index.length();
}
@Override
public AVector nonSparseValues() {
return data;
}
@Override
public Index nonSparseIndex() {
return Index.create(index);
}
public boolean includesIndex(int i) {
return index.indexPosition(i)>=0;
}
@Override
public void validate() {
int il=index.length();
int dl=data.length();
if (il!=dl) throw new VectorzException("Mismatched index and data length!");
if (il>length) throw new VectorzException("Index larger than length!");
if (dl>length) throw new VectorzException("Data larger than length!");
if (index.get(il-1)>=length) throw new VectorzException("Last element beyond length!");
}
@Override
public int length() {
return length;
}
/**
* Sets the length of this vector.
* @return
*/
public void setLength(int length) {
if ((length>this.length)||(index.last()
© 2015 - 2025 Weber Informatics LLC | Privacy Policy