All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mikera.vectorz.impl.JoinedArrayVector Maven / Gradle / Ivy

Go to download

Fast double-precision vector and matrix maths library for Java, supporting N-dimensional numeric arrays.

There is a newer version: 0.67.0
Show newest version
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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy