@Override public double norm(double power) { if (power < 0.0) { throw new IllegalArgumentException("Power must be >= 0"); } // We can special case certain powers. if (Double.isInfinite(power)) { return aggregate(Functions.MAX, Functions.ABS); } else if (power == 2.0) { return Math.sqrt(getLengthSquared()); } else if (power == 1.0) { double result = 0.0; Iterator<Element> iterator = this.iterateNonZero(); while (iterator.hasNext()) { result += Math.abs(iterator.next().get()); } return result; // TODO: this should ideally be used, but it's slower. // return aggregate(Functions.PLUS, Functions.ABS); } else if (power == 0.0) { return getNumNonZeroElements(); } else { return Math.pow(aggregate(Functions.PLUS, Functions.pow(power)), 1.0 / power); } }
@Override public int maxValueIndex() { int result = -1; double max = Double.NEGATIVE_INFINITY; int nonZeroElements = 0; Iterator<Element> iter = this.iterateNonZero(); while (iter.hasNext()) { nonZeroElements++; Element element = iter.next(); double tmp = element.get(); if (tmp > max) { max = tmp; result = element.index(); } } // if the maxElement is negative and the vector is sparse then any // unfilled element(0.0) could be the maxValue hence we need to // find one of those elements if (nonZeroElements < size && max < 0.0) { for (Element element : all()) { if (element.get() == 0.0) { return element.index(); } } } return result; }
@Override public Vector assign(Vector other) { return assign(other, Functions.SECOND); }
@Override public Vector normalize() { return divide(Math.sqrt(getLengthSquared())); }
@Override public Vector logNormalize() { return logNormalize(2.0, Math.sqrt(getLengthSquared())); }
return dotSelf(); int thisNumNonDefault = getNumNondefaultElements(); int thatNumNonDefault = x.getNumNondefaultElements(); if (isSequentialAccess() != x.isSequentialAccess()) { double log2ThisSize = Math.log(thisNumNonDefault) / LOG2; double log2ThatSize = Math.log(thatNumNonDefault) / LOG2; if (isSequentialAccess()) { reverseDotCost *= 0.71 * log2ThisSize - 12.3; Iterator<Element> iter = iterateNonZero(); while (iter.hasNext()) { Element element = iter.next();
@Override public double getDistanceSquared(Vector that) { if (size != that.size()) { throw new CardinalityException(size, that.size()); } double thisLength = getLengthSquared(); double thatLength = that.getLengthSquared(); double dot = dot(that); double distanceEstimate = thisLength + thatLength - 2 * dot; if (distanceEstimate > 1.0e-3 * (thisLength + thatLength)) { // The vectors are far enough from each other that the formula is accurate. return Math.max(distanceEstimate, 0); } else { return aggregate(that, Functions.PLUS, Functions.MINUS_SQUARED); } }
@Override public double maxValue() { if (size == 0) { return Double.NEGATIVE_INFINITY; } return aggregate(Functions.MAX, Functions.IDENTITY); }
/** * Copy the current vector in the most optimum fashion. Used by immutable methods like plus(), minus(). * Use this instead of vector.like().assign(vector). Sub-class can choose to override this method. * * @return a copy of the current vector. */ protected Vector createOptimizedCopy() { return createOptimizedCopy(this); }
@Override public double dot(Vector x) { if (size != x.size()) { throw new CardinalityException(size, x.size()); } if (this == x) { return getLengthSquared(); } return aggregate(x, Functions.PLUS, Functions.MULT); }
@Override public Vector divide(double x) { if (x == 1.0) { return clone(); } Vector result = createOptimizedCopy(); for (Element element : result.nonZeroes()) { element.set(element.get() / x); } return result; }
@Override public Vector times(Vector that) { if (size != that.size()) { throw new CardinalityException(size, that.size()); } if (this.getNumNondefaultElements() <= that.getNumNondefaultElements()) { return createOptimizedCopy(this).assign(that, Functions.MULT); } else { return createOptimizedCopy(that).assign(this, Functions.MULT); } }
@Override public Vector times(double x) { if (x == 0.0) { return like(); } return createOptimizedCopy().assign(Functions.mult(x)); }
@Override public Vector logNormalize() { return logNormalize(2.0, Math.sqrt(dotSelf())); }
@Override public Vector clone() { VectorView r = (VectorView) super.clone(); r.vector = vector.clone(); r.offset = offset; return r; }
Iterator<Element> iter = this.iterateNonZero(); while (iter.hasNext()) { val = Math.max(val, Math.abs(iter.next().get())); return Math.sqrt(dotSelf()); } else if (power == 1.0) { double val = 0.0; Iterator<Element> iter = this.iterateNonZero(); while (iter.hasNext()) { val += Math.abs(iter.next().get()); Iterator<Element> iter = this.iterateNonZero(); while (iter.hasNext()) { val += iter.next().get() == 0 ? 0 : 1; } else { double val = 0.0; Iterator<Element> iter = this.iterateNonZero(); while (iter.hasNext()) { Element element = iter.next();
@Override public double getDistanceSquared(Vector v) { if (size != v.size()) { throw new CardinalityException(size, v.size()); } // if this and v has a cached lengthSquared, dot product is quickest way to compute this. if (lengthSquared >= 0 && v instanceof AbstractVector && ((AbstractVector)v).lengthSquared >= 0) { return lengthSquared + v.getLengthSquared() - 2 * this.dot(v); } Vector randomlyAccessed; Iterator<Element> it; double d = 0.0; if (lengthSquared >= 0.0) { it = v.iterateNonZero(); randomlyAccessed = this; d += lengthSquared; } else { // TODO: could be further optimized, figure out which one is smaller, etc it = iterateNonZero(); randomlyAccessed = v; d += v.getLengthSquared(); } while (it.hasNext()) { Element e = it.next(); double value = e.get(); d += value * (value - 2.0 * randomlyAccessed.getQuick(e.index())); } //assert d > -1.0e-9; // round-off errors should never be too far off! return Math.abs(d); }
@Override public double getLengthSquared() { if (lengthSquared >= 0.0) { return lengthSquared; } return lengthSquared = dotSelf(); }