package mikera.vectorz.impl; import java.util.Iterator; import mikera.vectorz.AVector; /** * View class referencing a contiguous subvector of another vector. * @author Mike * */ public final class WrappedSubVector extends ASizedVector { private static final long serialVersionUID = 2323553136938665228L; private final AVector wrapped; private final int offset; private WrappedSubVector(AVector source, int offset, int length) { super(length); if (source instanceof WrappedSubVector) { // avoid stacking WrappedSubVectors by using underlying vector WrappedSubVector v=(WrappedSubVector)source; this.wrapped=v.wrapped; this.offset=offset+v.offset; } else { wrapped=source; this.offset=offset; } } public static WrappedSubVector wrap(AVector source, int offset, int length) { return new WrappedSubVector(source,offset,length); } @Override public Iterator<Double> iterator() { return new VectorIterator(wrapped,offset,length); } @Override public boolean isFullyMutable() { return wrapped.isFullyMutable(); } @Override public boolean isElementConstrained() { return wrapped.isElementConstrained(); } @Override public boolean isView() { return true; } @Override public boolean isZero() { return wrapped.isRangeZero(this.offset, this.length); } @Override public boolean isRangeZero(int start, int length) { return wrapped.isRangeZero(this.offset + start, length); } @Override public double get(int i) { checkIndex(i); return wrapped.unsafeGet(i+offset); } @Override public void set(int i, double value) { checkIndex(i); wrapped.unsafeSet(i+offset,value); } @Override public double unsafeGet(int i) { return wrapped.unsafeGet(i+offset); } @Override public void unsafeSet(int i, double value) { wrapped.unsafeSet(i+offset,value); } @Override public void add(AVector src, int offset) { wrapped.add(this.offset,src,offset,length); } @Override public void addToArray(int offset, double[] array, int arrayOffset, int length) { wrapped.addToArray(this.offset+offset, array, arrayOffset, length); } @Override public AVector subVector(int offset, int length) { int len=checkRange(offset,length); if (length==0) return Vector0.INSTANCE; if (len==length) return this; return wrapped.subVector(this.offset+offset, length); } @Override public void copyTo(int offset, AVector dest, int destOffset, int length) { wrapped.copyTo(this.offset+offset,dest,destOffset,length); } @Override public void copyTo(int offset, double[] dest, int destOffset, int length) { wrapped.copyTo(this.offset+offset,dest,destOffset,length); } @Override public void copyTo(int offset, double[] dest, int destOffset, int length, int stride) { wrapped.copyTo(this.offset+offset,dest,destOffset,length, stride); } @Override public AVector tryEfficientJoin(AVector a) { if (a instanceof WrappedSubVector) return tryEfficientJoin((WrappedSubVector)a); return null; } private AVector tryEfficientJoin(WrappedSubVector a) { if ((a.wrapped==this.wrapped)&&(a.offset==(this.offset+this.length))) { int newLength=this.length+a.length; if ((offset==0)&&(newLength==wrapped.length())) return wrapped; return new WrappedSubVector(wrapped,offset,newLength); } return null; } @Override public WrappedSubVector exactClone() { return new WrappedSubVector(wrapped.exactClone(),offset,length); } @Override public void addAt(int i, double v) { wrapped.addAt(offset+i,v); } @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; } }