package mikera.vectorz.impl; import mikera.vectorz.AVector; import mikera.vectorz.util.ErrorMessages; import mikera.vectorz.util.IntArrays; import mikera.vectorz.util.VectorzException; /** * Vector that addresses elements indexed into another source vector. * * Indexed elements are not necessarily distinct: two elements n the vector can refer to the same source element. * * @author Mike */ public final class IndexedSubVector extends BaseIndexedVector { private static final long serialVersionUID = -1411109918028367417L; private final AVector source; private IndexedSubVector(AVector source, int[] indexes) { super(indexes); this.source=source; } public static IndexedSubVector wrap(AVector source, int[] indexes) { return new IndexedSubVector(source,indexes); } @Override public void addToArray(double[] dest, int offset) { for (int i=0; i<length; i++) { dest[offset+i]+=source.unsafeGet(indexes[i]); } } @Override public void getElements(double[] dest, int offset) { for (int i=0; i<length; i++) { dest[offset+i]=source.unsafeGet(indexes[i]); } } @Override public AVector selectView(int... inds) { int[] ci=IntArrays.select(indexes,inds); return new IndexedSubVector(source,ci); } @Override public double get(int i) { return source.unsafeGet(indexes[i]); } @Override public void set(int i, double value) { source.unsafeSet(indexes[i],value); } @Override public double unsafeGet(int i) { return source.unsafeGet(indexes[i]); } @Override public void unsafeSet(int i, double value) { source.unsafeSet(indexes[i],value); } @Override public AVector subVector(int offset, int length) { if ((offset<0)||((offset+length)>this.length)) { throw new IndexOutOfBoundsException(ErrorMessages.invalidRange(this, offset, length)); } if (length==0) return Vector0.INSTANCE; if (length==this.length) return this; int[] newIndexes=new int[length]; for (int i=0; i<length; i++) { newIndexes[i]=indexes[offset+i]; } return wrap(this.source,newIndexes); } @Override public IndexedSubVector exactClone() { return IndexedSubVector.wrap(source.exactClone(), indexes.clone()); } @Override public void validate() { super.validate(); int slen=source.length(); for (int i=0; i<length; i++) { if ((indexes[i]<0)||(indexes[i]>=slen)) throw new VectorzException("Indexes out of range"); } } @Override public void addAt(int i, double v) { source.addAt(indexes[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; } }