📄 sparsefloatvector.java
字号:
if (dimension < 0 || dimension >= mNumDimensions) { String msg = "Dimension out of range." + " num dimensions in vector=" + mNumDimensions + " found dimension=" + dimension; throw new IndexOutOfBoundsException(msg); } int index = Arrays.binarySearch(mKeys,dimension); return index < 0 ? 0.0 : mValues[index]; } public double length() { return mLength; } static double computeLength(float[] vals) { double sum = 0; for (int i = 0; i < vals.length; ++i) { double val = vals[i]; sum += val * val; } return Math.sqrt(sum); } public Vector add(Vector v) { if (!(v instanceof SparseFloatVector)) return Matrices.add(this,v); verifyMatchingDimensions(v); SparseFloatVector spv = (SparseFloatVector) v; int[] keys1 = mKeys; int[] keys2 = spv.mKeys; int numMatching = 0; int index1 = 0; int index2 = 0; while (index1 < keys1.length && index2 < keys2.length) { ++numMatching; int comp = keys1[index1] - keys2[index2]; if (comp == 0) { ++index1; ++index2; } else if (comp < 0) { ++index1; } else { ++index2; } } while (index1 < keys1.length) { ++numMatching; ++index1; } while (index2 < keys2.length) { ++numMatching; ++index2; } float[] vals1 = mValues; float[] vals2 = spv.mValues; int[] resultKeys = new int[numMatching]; float[] resultVals = new float[numMatching]; int resultIndex = 0; index1 = 0; index2 = 0; while (index1 < keys1.length && index2 < keys2.length) { int comp = keys1[index1] - keys2[index2]; if (comp == 0) { resultKeys[resultIndex] = index1; resultVals[resultIndex] = vals1[index1] + vals2[index2]; ++index1; ++index2; ++resultIndex; } else if (comp < 0) { resultKeys[resultIndex] = index1; resultVals[resultIndex] = vals1[index1]; ++index1; ++resultIndex; } else { resultKeys[resultIndex] = index2; resultVals[resultIndex] = vals2[index2]; ++index2; ++resultIndex; } } while (index1 < keys1.length) { resultKeys[resultIndex] = index1; resultVals[resultIndex] = vals1[index1]; ++index1; ++resultIndex; } while (index2 < keys2.length) { resultKeys[resultIndex] = index2; resultVals[resultIndex] = vals2[index2]; ++index2; ++resultIndex; } double lengthSquared = 0; for (int i = 0; i < resultVals.length; ++i) lengthSquared += resultVals[i] * resultVals[i]; double length = Math.sqrt(lengthSquared); return new SparseFloatVector(resultKeys,resultVals,numDimensions(),length); } public double dotProduct(Vector v) { verifyMatchingDimensions(v); if (v instanceof SparseFloatVector) { SparseFloatVector spv = (SparseFloatVector) v; int[] keys1 = mKeys; float[] vals1 = mValues; int[] keys2 = spv.mKeys; float[] vals2 = spv.mValues; double sum = 0.0; int index1 = 0; int index2 = 0; while (index1 < keys1.length && index2 < keys2.length) { int comp = keys1[index1] - keys2[index2]; if (comp == 0) sum += vals1[index1++] * vals2[index2++]; else if (comp < 0) ++index1; else ++index2; } return sum; } else { double sum = 0.0; int[] keys1 = mKeys; float[] vals1 = mValues; for (int i = 0; i < keys1.length; ++i) sum += vals1[i] * v.value(keys1[i]); return sum; } } /** * Returns true if the specified object is a vector * with the same dimensionality and values as this vector. * * <p><i>Implementation Note:</i> This method requires a * get and comparison for each dimension with a non-zero * value in this vector. */ public boolean equals(Object that) { if (that instanceof SparseFloatVector) { SparseFloatVector thatVector = (SparseFloatVector) that; if (mKeys.length != thatVector.mKeys.length) return false; if (mNumDimensions != thatVector.mNumDimensions) return false; if (mLength != thatVector.mLength) return false; for (int i = 0; i < mKeys.length; ++i) if (mKeys[i] != thatVector.mKeys[i]) return false; for (int i = 0; i < mValues.length; ++i) if (mValues[i] != thatVector.mValues[i]) return false; return true; } else if (that instanceof Vector) { Vector thatVector = (Vector) that; if (mNumDimensions != thatVector.numDimensions()) return false; if (mLength != thatVector.length()) return false; for (int i = 0; i < mKeys.length; ++i) if (mValues[i] != thatVector.value(mKeys[i])) return false; return true; } return super.equals(that); } /** * Returns the hash code for this sparse float vector. The * hash code is the same as it would be for the equivalent * dense vector. * * <p><i>Implementation Note:</i> hashing requires a long integer * shift and mask, as well as a normal integer multiply and * add for each dimension with a value. * * @return The hash code for this sparse float vector. */ public int hashCode() { int code = 1; int numDimensions = numDimensions(); for (int i = 0; i < mValues.length; ++i) { long v = Double.doubleToLongBits(mValues[i]); int valHash = (int)(v^(v>>>32)); code = 31 * code + valHash; } return code; } public double cosine(Vector v) { double cosine = dotProduct(v) / (v.length() * length()); return (cosine < -1.0 ? -1.0 : (cosine > 1.0 ? 1.0 : cosine)); } private Object writeReplace() { return new Externalizer(this); } static class Externalizer extends AbstractExternalizable { static final long serialVersionUID = -7216149275959287094L; final SparseFloatVector mVector; public Externalizer() { this(null); } public Externalizer(SparseFloatVector vector) { mVector = vector; } public Object read(ObjectInput in) throws IOException { int len = in.readInt(); int numDimensions = in.readInt(); double length = in.readDouble(); int[] keys = new int[len]; for (int i = 0; i < keys.length; ++i) keys[i] = in.readInt(); float[] values = new float[len]; for (int i = 0; i < len; ++i) values[i] = in.readFloat(); return new SparseFloatVector(keys,values,numDimensions,length); } public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(mVector.mKeys.length); out.writeInt(mVector.mNumDimensions); out.writeDouble(mVector.mLength); for (int i = 0; i < mVector.mKeys.length; ++i) out.writeInt(mVector.mKeys[i]); for (int i = 0; i < mVector.mValues.length; ++i) out.writeFloat(mVector.mValues[i]); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -