mikera.vectorz.impl.JoinedArrayVector Maven / Gradle / Ivy
Show all versions of vectorz Show documentation
package mikera.vectorz.impl;
import java.util.Arrays;
import mikera.arrayz.INDArray;
import mikera.vectorz.AVector;
import mikera.vectorz.Op;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;
/**
* Class representing a join of one or more array segments, i.e. the vector is constructed
* from a sequence of fixed chunks of double[] arrays
*
* @author Mike
*/
public final class JoinedArrayVector extends AJoinedVector {
private static final long serialVersionUID = -8470277860344236392L;
private final int numArrays; // number of joined arrays
private final double[][] data; // source arrays
private final int[] offsets; // offsets into source arrays
private final int[] pos; // position of each array within vector. contains one extra element
private JoinedArrayVector(int length, double[][] newData,int[] offsets, int[] pos) {
super(length);
this.numArrays=newData.length;
this.offsets=offsets;
this.pos=pos;
this.data=newData;
}
public static final JoinedArrayVector create(AVector v) {
int length=v.length();
double[][] data=new double[1][];
data[0]=new double[length];
v.getElements(data[0], 0);
JoinedArrayVector jav=new JoinedArrayVector(length,data,new int[1],new int[] {0,length});
return jav;
}
public static JoinedArrayVector wrap(ADenseArrayVector v) {
return new JoinedArrayVector(v.length(),
new double[][] {v.getArray()},
new int[] {v.getArrayOffset()},
new int[] {0,v.length()});
}
public int numArrays() {
return this.numArrays;
}
// finds the number of the array that contains a specific index position
private int findArrayNum(int index) {
assert((index>=0)&&(index>1;
int p=pos[m];
if (index=p2) {i=m+1; continue;}
return m;
}
return i;
}
private int subLength(int j) {
return pos[j+1]-pos[j];
}
@Override
public ArraySubVector getComponent(int i) {
return ArraySubVector.wrap(data[i], offsets[i], subLength(i));
}
@Override
public boolean isView() {
return true;
}
@Override
public boolean isFullyMutable() {
return true;
}
@Override
public double get(int i) {
if ((i<0)||(i>=length)) throw new IndexOutOfBoundsException(ErrorMessages.invalidIndex(this, i));
int ai=findArrayNum(i);
return data[ai][i-pos[ai]+offsets[ai]];
}
@Override
public double unsafeGet(int i) {
int ai=findArrayNum(i);
return data[ai][i-pos[ai]+offsets[ai]];
}
@Override
public void set(int i, double value) {
if ((i<0)||(i>=length)) throw new IndexOutOfBoundsException(ErrorMessages.invalidIndex(this, i));
int ai=findArrayNum(i);
data[ai][i-pos[ai]+offsets[ai]]=value;
}
@Override
public void unsafeSet(int i, double value) {
int ai=findArrayNum(i);
data[ai][i-pos[ai]+offsets[ai]]=value;
}
@Override
public void addAt(int i, double value) {
int ai=findArrayNum(i);
data[ai][i-pos[ai]+offsets[ai]]+=value;
}
@Override
public double elementSum() {
double result=0.0;
for (int j=0; j=pos[j+1]) continue; // skip until adding at right place
int segmentOffset=Math.max(0,offset-pos[j]);
int len=Math.min(subLength(j)-segmentOffset, offset+alen-pos[j]);
if (len>0) {
a.addToArray(aOffset+pos[j]+segmentOffset-offset, data[j], offsets[j]+segmentOffset, len);
}
}
}
@Override
public void addToArray(int offset, double[] a, int aOffset, int length) {
int alen=length;
for (int j=0; j=pos[j+1]) continue; // skip until adding at right place
int segmentOffset=Math.max(0,offset-pos[j]);
int len=Math.min(subLength(j)-segmentOffset, offset+alen-pos[j]);
if (len>0) {
DoubleArrays.add(data[j], offsets[j]+segmentOffset,a, aOffset+pos[j]+segmentOffset-offset, len);
}
}
}
@Override
public void addProduct(AVector a, AVector b, double factor) {
addProduct(a,0,b,0,factor);
}
@Override
public void addMultiple(AVector a, double factor) {
addMultiple(0,a,0,length(),factor);
}
@Override
public void addMultiple(int offset, AVector a, int aOffset, int length, double factor) {
int alen=length;
for (int j=0; j=pos[j+1]) continue; // skip until adding at right place
int segmentOffset=Math.max(0,offset-pos[j]);
int len=Math.min(subLength(j)-segmentOffset, offset+alen-pos[j]);
if (len>0) {
a.addMultipleToArray(factor,aOffset+pos[j]+segmentOffset-offset, data[j], offsets[j]+segmentOffset, len);
}
}
}
@Override
public void addMultipleToArray(double factor,int offset, double[] array, int arrayOffset, int length) {
int startArray=findArrayNum(offset);
int endPos=offset+length; // end poition in this vector
for (int j=startArray, sp=pos[j]; sp0);
clen-=skip;
DoubleArrays.addMultiple(array, arrayOffset, sa, soffset+skip, clen, factor);
}
arrayOffset+=clen;
}
}
@Override
public void addProduct(AVector a, int aOffset, AVector b, int bOffset, double factor) {
for (int j=0; jthis.length)) {
throw new IndexOutOfBoundsException(ErrorMessages.invalidRange(this, start, length));
}
if (length==this.length) return this;
if (length==0) return Vector0.INSTANCE;
int a=findArrayNum(start);
int b=findArrayNum(start+length-1);
int n=b-a+1;
// special case if start and end fall on same array
if (n==1) return Vectorz.wrap(data[a], offsets[a]+(start-pos[a]), length);
double[][] newData=Arrays.copyOfRange(data, a, b+1);
int[] offs=new int[n];
offs[0]=offsets[a]+(start-pos[a]);
for (int j=1; j