package mikera.vectorz.impl;
import java.nio.DoubleBuffer;
import mikera.arrayz.INDArray;
import mikera.vectorz.AVector;
import mikera.vectorz.Op;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.IntArrays;
import mikera.vectorz.util.VectorzException;
/**
* A vector that represents the concatenation of many vectors.
*
* @author Mike
*
*/
public final class JoinedMultiVector extends AJoinedVector {
private static final long serialVersionUID = 6226205676178066609L;
/**
* The number of segments
*/
private final int n;
/**
* The set of vectors that define all the segments of this JoinedMultiVector
*/
private final AVector[] vecs;
// array of split positions [0, ...... , length] with length n+1
private final int[] splits;
private JoinedMultiVector(int length, AVector[] vecs, int[] splits) {
super(length);
n=vecs.length;
this.vecs=vecs;
this.splits=splits;
}
private JoinedMultiVector(AVector[] vs) {
this(sumOfLengths(vs),vs,new int[vs.length+1]);
int j=0;
for (int i=0; ithis.length)||(length<0)) throw new IndexOutOfBoundsException(ErrorMessages.invalidRange(this,offset, length));
int i1=IntArrays.indexLookup(splits, start);
int i2=IntArrays.indexLookup(splits, end-1);
if (i1==i2) {
offset-=splits[i1];
vecs[i1].addToArray(offset, array,arrayOffset,length);
return;
}
vecs[i1].addToArray(offset-splits[i1], array, arrayOffset,splits[i1+1]-offset);
vecs[i2].addToArray(0, array, arrayOffset+splits[i2]-offset,end-splits[i2]);
for (int i=i1+1;ithis.length)||(length<0)) throw new IndexOutOfBoundsException(ErrorMessages.invalidRange(this,offset, length));
int i1=IntArrays.indexLookup(splits, start);
int i2=IntArrays.indexLookup(splits, end-1);
if (i1==i2) {
offset-=splits[i1];
vecs[i1].addMultipleToArray(factor,offset, array,arrayOffset,length);
return;
}
vecs[i1].addMultipleToArray(factor,offset-splits[i1], array, arrayOffset,splits[i1+1]-offset);
vecs[i2].addMultipleToArray(factor,array, arrayOffset+splits[i2]-offset);
for (int i=i1+1;ithis.length)||(length<0)) throw new IndexOutOfBoundsException(ErrorMessages.invalidRange(this,start, length));
if (length==this.length) return this;
int i1=IntArrays.indexLookup(splits, start);
int i2=IntArrays.indexLookup(splits, end-1);
if (i1==i2) {
return vecs[i1].subVector(start-splits[i1], length);
}
int nn =i2-i1+1;
AVector[] nvecs=new AVector[nn];
nvecs[0]=vecs[i1].subVector(start-splits[i1], splits[i1+1]-start);
nvecs[nn-1]=vecs[i2].subVector(0, end-splits[i2]);
for (int i=1; i<(i2-i1); i++) {
nvecs[i]=vecs[i1+i];
}
return new JoinedMultiVector(nvecs);
}
@Override
public AVector tryEfficientJoin(AVector v) {
if (v instanceof JoinedMultiVector) return join((JoinedMultiVector)v);
if (v instanceof JoinedVector) return join((JoinedVector)v);
AVector ej=vecs[n-1].tryEfficientJoin(v);
if (ej!=null) {
AVector[] nvecs=vecs.clone();
nvecs[n-1]=ej;
return new JoinedMultiVector(nvecs);
} else {
AVector[] nvecs=new AVector[n+1];
System.arraycopy(vecs, 0, nvecs, 0, n);
nvecs[n]=v;
return new JoinedMultiVector(nvecs);
}
}
public AVector join(JoinedMultiVector v) {
AVector[] nvecs=new AVector[n+v.n];
System.arraycopy(vecs, 0, nvecs, 0, n);
System.arraycopy(v.vecs, 0, nvecs, n, v.n);
return new JoinedMultiVector(nvecs);
}
public AVector join(JoinedVector v) {
AVector ej=vecs[n-1].tryEfficientJoin(v.left);
if (ej!=null) {
AVector[] nvecs=new AVector[n+1];
System.arraycopy(vecs, 0, nvecs, 0, n);
nvecs[n-1]=ej;
nvecs[n]=v.right;
return new JoinedMultiVector(nvecs);
} else {
AVector[] nvecs=new AVector[n+2];
System.arraycopy(vecs, 0, nvecs, 0, n);
nvecs[n]=v.left;
nvecs[n+1]=v.right;
return new JoinedMultiVector(nvecs);
}
}
@Override
public void add(AVector a) {
assert(length()==a.length());
if (a instanceof JoinedMultiVector) {
add((JoinedMultiVector)a);
} else {
add(a,0);
}
}
public void add(JoinedMultiVector a) {
if (IntArrays.equals(splits, a.splits)) {
for (int i=0; iresult) result=m;
}
return result;
}
@Override
public double elementMin() {
double result=vecs[0].elementMin();
for (int i=0; i
Ads help maintain this website.