Package mikera.vectorz.impl

Source Code of mikera.vectorz.impl.ADenseArrayVector

package mikera.vectorz.impl;

import java.nio.DoubleBuffer;
import java.util.Arrays;

import mikera.arrayz.INDArray;
import mikera.arrayz.impl.IDenseArray;
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.IntArrays;
import mikera.vectorz.util.VectorzException;

/**
* Base class for mutable dense vectors backed by a double[] array with a fixed stride of 1
*
* The double array can be directly accessed for performance purposes
*
* @author Mike
*/
@SuppressWarnings("serial")
public abstract class ADenseArrayVector extends AStridedVector implements IDenseArray {
 
  protected ADenseArrayVector(int length, double[] data) {
    super(length,data);
  }

  /**
   * ADenseArrayVector has a fixed stride of 1, which enables efficient operations
   * on arrays
   */
  @Override
  public final int getStride() {
    return 1;
  }

  /**
   * Returns a vector referencing a sub-vector of the current vector
   *
   * @param offset
   * @param length
   * @return
   */
  public AVector subVector(int offset, int length) {
    int len = checkRange(offset,length);
    if (length == 0) return Vector0.INSTANCE;
    if (length == len) return this;
    return new ArraySubVector(this, offset, length);
  }

  @Override
  public ArrayIndexScalar slice(int position) {
    checkIndex(position);
    return new ArrayIndexScalar(getArray(), getArrayOffset() + position);
  }
 
  @Override
  public AVector selectView(int... inds) {
    inds=inds.clone();
    IntArrays.add(inds,getArrayOffset());
    return IndexedArrayVector.wrap(getArray(), inds);
  }

  public boolean isPackedArray() {
    return (getArrayOffset() == 0) && (length() == getArray().length);
  }

  @Override
  public boolean isView() {
    // ArrayVector is usually a view
    return true;
  }

  @Override
  public boolean isZero() {
    return DoubleArrays.isZero(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public boolean isRangeZero(int start, int length) {
    return DoubleArrays.isZero(getArray(), getArrayOffset()+start, length);
  }

  @Override
  public void toDoubleBuffer(DoubleBuffer dest) {
    dest.put(getArray(), getArrayOffset(), length());
  }

  @Override
  public void getElements(double[] data, int offset) {
    System.arraycopy(getArray(), getArrayOffset(), data, offset, length());
  }
 
  @Override
  public ADenseArrayVector dense() {
    // we are already dense!
    return this;
  }

  @Override
  public void fillRange(int offset, int length, double value) {
    assert ((offset >= 0) && (length >= 0) && ((offset + length) <= length()));
    double[] arr = getArray();
    int off = getArrayOffset();
    Arrays.fill(arr, off + offset, off + offset + length, value);
  }

  @Override
  public void set(AVector a) {
    checkSameLength(a);
    a.getElements(getArray(), getArrayOffset());
  }

  @Override
  public void set(AVector a, int offset) {
    assert (offset >= 0);
    assert (offset + length() <= a.length());
    a.copyTo(offset, this, 0, length());
  }

  @Override
  public void setRange(int offset, double[] data, int dataOffset, int length) {
    System.arraycopy(data, dataOffset, getArray(), getArrayOffset()
        + offset, length);
  }

  @Override
  public void setElements(int pos,double[] values, int offset, int length) {
    checkRange(pos,length);
    System.arraycopy(values, offset, getArray(), getArrayOffset()+pos, length);
  }

  @Override
  public abstract double get(int i);

  @Override
  public abstract void set(int i, double value);

  @Override
  public abstract double unsafeGet(int i);

  @Override
  public abstract void unsafeSet(int i, double value);

  @Override
  public void add(AVector src) {
    src.addToArray(0, getArray(), getArrayOffset(), length());
  }

  @Override
  public void add(ADenseArrayVector v) {
    add(v, 0);
  }

  @Override
  public void add(AVector src, int srcOffset) {
    src.addToArray(srcOffset, getArray(), getArrayOffset(), length);
  }

  @Override
  public void add(int offset, AVector src) {
    src.addToArray(0, getArray(), getArrayOffset() + offset, length);
  }

  public void add(int offset, ADenseArrayVector src) {
    int length = src.length();
    DoubleArrays.add(src.getArray(), src.getArrayOffset(), getArray(),
        offset + getArrayOffset(), length);
  }

  public void add(int offset, ADenseArrayVector src, int srcOffset, int length) {
    DoubleArrays.add(src.getArray(), src.getArrayOffset() + srcOffset,
        getArray(), offset + getArrayOffset(), length);
  }

  @Override
  public void addMultiple(AVector v, double factor) {
    int length = checkSameLength(v);
    v.addMultipleToArray(factor, 0, getArray(), getArrayOffset(), length);
  }

  @Override
  public void scaleAdd(double factor, double constant) {
    DoubleArrays.scaleAdd(getArray(), getArrayOffset(), length(), factor,
        constant);
  }

  @Override
  public void add(double constant) {
    DoubleArrays.add(getArray(), getArrayOffset(), length(), constant);
  }

  @Override
  public void addProduct(AVector a, int aOffset, AVector b, int bOffset,
      double factor) {
    int length = length();
    double[] array = getArray();
    int offset = getArrayOffset();
    a.addProductToArray(factor, aOffset, b, bOffset, array, offset, length);
  }

  @Override
  public void addToArray(int offset, double[] destData, int destOffset, int length) {
    double[] data = getArray();
    int dataOffset = getArrayOffset() + offset;
    DoubleArrays.add(data, dataOffset, destData, destOffset, length);
  }
 
  @Override
  public void addToArray(double[] dest, int offset, int stride) {
    double[] data = getArray();
    int dataOffset = getArrayOffset();

    for (int i = 0; i < length; i++) {
      dest[offset + i*stride] += data[dataOffset + i];
    }
  }
 
  @Override
  public void addProduct(AVector a, AVector b) {
    int len = length();
    assert (len == a.length());
    assert (len == b.length());
    double[] array = getArray();
    int offset = getArrayOffset();
    if (b instanceof ADenseArrayVector) {
      a.addProductToArray(1.0, 0, (ADenseArrayVector)b, 0, array, offset, len);
    } else {
      a.addProductToArray(1.0, 0, b, 0, array, offset, len);     
    }
  } 

  @Override
  public void addProduct(AVector a, AVector b, double factor) {
    if (factor==0) return;
    int len = length();
    assert (len == a.length());
    assert (len == b.length());
    double[] array = getArray();
    int offset = getArrayOffset();
    if (b instanceof ADenseArrayVector) {
      a.addProductToArray(factor, 0, (ADenseArrayVector)b, 0, array, offset, len);
    } else {
      a.addProductToArray(factor, 0, b, 0, array, offset, len);     
    }
  }

  @Override
  public void addMultipleToArray(double factor, int offset, double[] array,
      int arrayOffset, int length) {
    if (factor==0) return;
    double[] data = getArray();
    int dataOffset = getArrayOffset() + offset;

    for (int i = 0; i < length; i++) {
      array[i + arrayOffset] += factor * data[i + dataOffset];
    }
  }

  @Override
  public void addProductToArray(double factor, int offset, AVector other,
      int otherOffset, double[] array, int arrayOffset, int length) {
    if (factor==0) return;
    if (other instanceof ADenseArrayVector) {
      addProductToArray(factor, offset, (ADenseArrayVector) other,
          otherOffset, array, arrayOffset, length);
      return;
    }
    assert (offset >= 0);
    assert (offset + length <= length());
    double[] thisArray = getArray();
    offset += getArrayOffset();
    for (int i = 0; i < length; i++) {
      array[i + arrayOffset] += factor * thisArray[i + offset]
          * other.unsafeGet(i + otherOffset);
    }
  }

  @Override
  public void addProductToArray(double factor, int offset,
      ADenseArrayVector other, int otherOffset, double[] array,
      int arrayOffset, int length) {
    if (factor==0) return;
    assert (offset >= 0);
    assert (offset + length <= length());
    double[] otherArray = other.getArray();
    otherOffset += other.getArrayOffset();
    double[] thisArray = getArray();
    offset += getArrayOffset();
    for (int i = 0; i < length; i++) {
      array[i + arrayOffset] += factor * thisArray[i + offset]
          * otherArray[i + otherOffset];
    }
  }

  public void add(ADenseArrayVector src, int srcOffset) {
    src.checkRange(srcOffset,length);
    double[] vdata = src.getArray();
    double[] data = getArray();
    int offset = getArrayOffset();
    int voffset = src.getArrayOffset() + srcOffset;
    for (int i = 0; i < length; i++) {
      data[offset + i] += vdata[voffset + i];
    }
  }
 
  @Override
  public void add(double[] data, int offset) {
    DoubleArrays.add(data, offset, getArray(), getArrayOffset(), length);
  }

  @Override
  public void addAt(int i, double v) {
    assert ((i >= 0) && (i < length())); // just an assert since this is unchecked
    double[] data = getArray();
    int offset = getArrayOffset();
    data[i + offset] += v;
  }

  @Override
  public double dotProduct(double[] data, int offset) {
    return DoubleArrays.dotProduct(getArray(), getArrayOffset(), data, offset, length());
  }

  @Override
  public double dotProduct(AVector v) {
    int length = checkSameLength(v);
   
    if (v instanceof ADenseArrayVector) {
      ADenseArrayVector vv = (ADenseArrayVector) v;
      return DoubleArrays.dotProduct(getArray(), getArrayOffset(),
          vv.getArray(), vv.getArrayOffset(), length);
    } else {
      return v.dotProduct(this.getArray(), this.getArrayOffset());
    }
  }

  @Override
  public void abs() {
    DoubleArrays.abs(getArray(), getArrayOffset(), length());
  }

  @Override
  public void log() {
    DoubleArrays.log(getArray(), getArrayOffset(), length());
  }

  @Override
  public void exp() {
    DoubleArrays.exp(getArray(), getArrayOffset(), length());
  }

  @Override
  public void applyOp(Op op) {
    op.applyTo(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public ADenseArrayVector applyOpCopy(Op op) {
    int len=length();
    Vector v=Vector.createLength(len);
    op.applyTo(v.getArray(), v.getArrayOffset(), len);
    return v;
  }

  @Override
  public double elementSum() {
    return DoubleArrays.elementSum(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public double elementPowSum(double exponent) {
    return DoubleArrays.elementPowSum(getArray(), getArrayOffset(), length(),exponent);
  }
 
  @Override
  public double elementAbsPowSum(double exponent) {
    return DoubleArrays.elementAbsPowSum(getArray(), getArrayOffset(), length(),exponent);
  }
 
  @Override
  public double elementProduct() {
    return DoubleArrays.elementProduct(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public double elementMax(){
    return DoubleArrays.elementMax(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public double elementMin(){
    return DoubleArrays.elementMin(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public double maxAbsElement(){
    return DoubleArrays.elementMaxAbs(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public int minElementIndex(){
    return DoubleArrays.elementMinIndex(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public int maxElementIndex(){
    return DoubleArrays.elementMaxIndex(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public int maxAbsElementIndex(){
    return DoubleArrays.elementMaxAbsIndex(getArray(), getArrayOffset(), length());
  }

  @Override
  public long nonZeroCount() {
    return DoubleArrays
        .nonZeroCount(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public int[] nonZeroIndices() {
    return DoubleArrays.nonZeroIndices(getArray(), getArrayOffset(), length());
  }

  @Override
  public void square() {
    DoubleArrays.square(getArray(), getArrayOffset(), length());
  }
 
  @Override
  public Vector squareCopy() {
    double[] ds=toDoubleArray();
    DoubleArrays.square(ds);
    return Vector.wrap(ds);
  }

  @Override
  public void sqrt() {
    DoubleArrays.sqrt(getArray(), getArrayOffset(), length());
  }

  /**
   * Sets each component of the vector to its sign value (-1, 0 or 1)
   */
  public void signum() {
    DoubleArrays.signum(getArray(), getArrayOffset(), length());
  }

  @Override
  public void multiply(AVector v) {
    v.multiplyTo(getArray(), getArrayOffset());
  }

  @Override
  public void multiply(double[] src, int srcOffset) {
    int len = length();
    double[] cdata = getArray();
    int coffset = getArrayOffset();
    for (int i = 0; i < len; i++) {
      cdata[i + coffset] *= src[i + srcOffset];
    }
  }

  @Override
  public void multiplyTo(double[] dest, int destOffset) {
    DoubleArrays.arraymultiply(getArray(), getArrayOffset(), dest, destOffset,
        length());
  }

  @Override
  public void divide(AVector v) {
    v.divideTo(getArray(), getArrayOffset());
  }

  @Override
  public void divide(double[] data, int offset) {
    DoubleArrays.arraydivide(data, offset, getArray(), getArrayOffset(), length());
  }

  @Override
  public void divideTo(double[] data, int offset) {
    DoubleArrays.arraydivide(getArray(), getArrayOffset(), data, offset, length());
  }

  @Override
  public void copyTo(int start, AVector dest, int destOffset, int length) {
    dest.setElements(destOffset, getArray(), getArrayOffset()+start, length);
  }

  public void copyTo(int offset, ADenseArrayVector dest, int destOffset, int length) {
    double[] src = getArray();
    int off = getArrayOffset();
    double[] dst = dest.getArray();
    System.arraycopy(src, off + offset, dst, dest.getArrayOffset()
        + destOffset, length);
  }
 
  @Override
  public void copyTo(int offset, double[] dest, int destOffset, int length, int stride) {
    for (int i=0; i<length; i++) {
      dest[destOffset+i*stride]=data[i+offset];
    }
  }

  @Override
  public void copyTo(int offset, double[] dest, int destOffset, int length) {
    double[] src = getArray();
    int off = getArrayOffset();
    System.arraycopy(src, off + offset, dest, destOffset, length);
  }

  public void addMultiple(ADenseArrayVector v, double factor) {
    int length = checkSameLength(v);
    v.addMultipleToArray(factor, 0, getArray(), getArrayOffset(), length);
  }
 
  @Override
  public void addMultiple(int offset, AVector src, int srcOffset, int length, double factor) {
    checkRange(offset,length);
    src.checkRange(srcOffset,length);
    if (factor==0.0) return;
    int tOffset=offset+this.getArrayOffset();
    src.addMultipleToArray(factor, srcOffset, this.getArray(), tOffset, length);
  }

  @Override
  public double magnitudeSquared() {
    return DoubleArrays.elementSquaredSum(data, getArrayOffset(), length);
  }

  @Override
  public double magnitude() {
    return Math.sqrt(magnitudeSquared());
  }

  @Override
  public void fill(double value) {
    int offset = getArrayOffset();
    Arrays.fill(getArray(), offset, offset + length, value);
  }

  @Override
  public void pow(double exponent) {
    int len = length();
    double[] data = getArray();
    int offset = getArrayOffset();
    DoubleArrays.pow(data, offset, len, exponent);
  }

  @Override
  public void reciprocal() {
    DoubleArrays.reciprocal(getArray(), getArrayOffset(), length());
  }

  @Override
  public void clamp(double min, double max) {
    DoubleArrays.clamp(getArray(), getArrayOffset(), length(), min, max);
  }

  @Override
  public void multiply(double factor) {
    DoubleArrays.multiply(getArray(), getArrayOffset(), length(), factor);
  }

  @Override
  public AVector tryEfficientJoin(AVector v) {
    if (v instanceof ADenseArrayVector) return join((ADenseArrayVector) v);
    if (v instanceof JoinedArrayVector) return join((JoinedArrayVector) v);
    return null;
  }

  public AVector join(ADenseArrayVector v) {
    if ((v.getArray() == getArray())
        && ((getArrayOffset() + length) == v.getArrayOffset())) {
      return Vectorz.wrap(getArray(), getArrayOffset(), length + v.length());
    }
    return JoinedArrayVector.joinVectors(this, v);
  }

  public JoinedArrayVector join(JoinedArrayVector v) {
    return JoinedArrayVector.wrap(this).join(v);
  }
 
  @Override
  public boolean equals(INDArray v) {
    if (v.dimensionality()!=1) return false;
    int len=length();
    if (len != v.getShape(0)) return false;
   
    return v.equalsArray(getArray(), getArrayOffset());
  }

  @Override
  public boolean equals(AVector v) {
    if (v==this) return true;
    int len = length();
    if (v.length() != len) return false;
    return v.equalsArray(getArray(), getArrayOffset());
  }

  @Override
  public boolean equalsArray(double[] data, int offset) {
    return DoubleArrays.equals(data, offset, getArray(), getArrayOffset(), length);
  }

  @Override
  public boolean equalsArray(double[] data) {
    if (length() != data.length) return false;
    return equalsArray(data,0);
  }
 
  @Override
  public boolean elementsEqual(double value) {
    int length=length();
    double[] data = getArray();
    int offset = getArrayOffset();
    return DoubleArrays.elementsEqual(data,offset,length,value);
  }

  @Override
  public void validate() {
    int length = length();
    double[] data = getArray();
    int offset = getArrayOffset();
    if ((offset < 0) || (offset + length > data.length)) {
      throw new VectorzException("ArrayVector out of bounds");
    }
    super.validate();
  }
}
TOP

Related Classes of mikera.vectorz.impl.ADenseArrayVector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.