package mikera.vectorz.impl;
import mikera.matrixx.AMatrix;
import mikera.vectorz.AVector;
/**
* Abstract Vector class representing a view over a matrix
*
* Supports arbitrary indexing into the underlying matrix
*
* @author Mike
*/
@SuppressWarnings("serial")
public abstract class AMatrixViewVector extends ASizedVector {
protected AMatrix source;
protected AMatrixViewVector(AMatrix source, int length) {
super(length);
this.source=source;
}
protected abstract int calcRow(int i);
protected abstract int calcCol(int i);
@Override
public void set(int i, double value) {
checkIndex(i);
// we assume unsafe is OK, i.e. calculations are correct given correct i
source.unsafeSet(calcRow(i),calcCol(i),value);
}
@Override
public void addAt(int i, double v) {
int r=calcRow(i);
int c=calcCol(i);
source.unsafeSet(r,c,source.unsafeGet(r,c)+v);
}
@Override
public void unsafeSet(int i, double value) {
// we assume unsafe is OK, i.e. both i and calculations are correct
source.unsafeSet(calcRow(i),calcCol(i),value);
}
@Override
public double get(int i) {
checkIndex(i);
// we assume unsafe is OK, i.e. calculations are correct given correct i
return source.unsafeGet(calcRow(i),calcCol(i));
}
@Override
public double unsafeGet(int i) {
return source.unsafeGet(calcRow(i),calcCol(i));
}
@Override
public void getElements(double[] data, int offset) {
for (int i=0; i<length; i++) {
data[offset+i]=source.unsafeGet(calcRow(i), calcCol(i));
}
}
@Override
public MatrixIndexScalar slice(int i) {
return MatrixIndexScalar.wrap(source, calcRow(i), calcCol(i));
}
@Override
public boolean equals(AVector v) {
if (v==this) return true;
if (v.length()!=length) return false;
for (int i=0; i<length; i++) {
if (v.unsafeGet(i)!=source.unsafeGet(calcRow(i), calcCol(i))) return false;
}
return true;
}
@Override
public boolean equalsArray(double[] data, int offset) {
for (int i=0; i<length; i++) {
if (unsafeGet(i)!=data[offset++]) return false;
}
return true;
}
}