package mikera.vectorz.impl;
import mikera.vectorz.AVector;
/**
* Vector with an increasing triangular index. Useful for triangular and symmetric matrix subviews
*
* @author Mike
*/
public final class TriangularIndexedVector extends AArrayVector {
private static final long serialVersionUID = -3987292933848795478L;
private int offset;
private int baseStride2;
protected TriangularIndexedVector(int length, double[] data, int offset, int baseStride2) {
super(length, data);
this.offset=offset;
this.baseStride2=baseStride2;
}
public static TriangularIndexedVector wrap(int length, double[] data, int offset, int baseStride) {
return new TriangularIndexedVector(length, data, offset, baseStride*2);
}
@Override
protected int index(int i) {
return offset+(((baseStride2+i+1)*i)>>1);
}
@Override
public double get(int i) {
checkIndex(i);
return data[index(i)];
}
@Override
public void set(int i, double value) {
checkIndex(i);
data[index(i)]=value;
}
@Override
public double unsafeGet(int i) {
return data[index(i)];
}
@Override
public void unsafeSet(int i, double value) {
data[index(i)]=value;
}
@Override
public AVector subVector(int start, int length) {
int len=checkRange(start,length);
if (length==0) return Vector0.INSTANCE;
if (length==len) return this;
return wrap(length,data,index(start),(baseStride2>>1)+start);
}
@Override
public AVector exactClone() {
return new TriangularIndexedVector(length,data.clone(),offset,baseStride2);
}
@Override
public double dotProduct(double[] data, int offset) {
double result=0.0;
for (int i=0; i<length; i++) {
result+=data[offset+i]*unsafeGet(i);
}
return result;
}
}