@Override
	public double compareDetail(LSHVector op2, StringBuilder buf) {
		int iter, enditer, iter2, enditer2;
		LSHCosineVector op = (LSHCosineVector) op2;

		ArrayList<HashEntry> a_only = new ArrayList<HashEntry>();
		ArrayList<HashEntry> b_only = new ArrayList<HashEntry>();
		ArrayList<HashEntry> ab_both = new ArrayList<HashEntry>();

		buf.append("lena=").append(getLength()).append('\n');
		buf.append("lenb=").append(op2.getLength()).append('\n');
		iter = 0;
		enditer = hash.length;
		iter2 = 0;
		enditer2 = op.hash.length;

		double res = 0.0;
		int intersectcount = 0;
		int hash1, hash2;
		if ((iter != enditer) && (iter2 != enditer2)) {
			hash1 = hash[iter].getHash();
			hash2 = op.hash[iter2].getHash();
			for (;;) {
				if (hash1 == hash2) {
					ab_both.add(hash[iter]);
					ab_both.add(op.hash[iter2]);
					int t1 = hash[iter].getTF();
					int t2 = op.hash[iter2].getTF();
					if (t1 < t2) {
						double w1 = hash[iter].getCoeff();
						res += w1 * w1;
						intersectcount += t1;
					}
					else {
						double w2 = op.hash[iter2].getCoeff();
						res += w2 * w2;
						intersectcount += t2;
					}
					++iter;
					++iter2;
					if (iter == enditer) {
						break;
					}
					if (iter2 == enditer2) {
						break;
					}
					hash1 = hash[iter].getHash();
					hash2 = op.hash[iter2].getHash();
				}
				else if (hash1 + 0x80000000 < hash2 + 0x80000000) {// This needs to be an UNSIGNED comparison of hash1 and hash2
					a_only.add(hash[iter]);
					++iter;
					if (iter == enditer) {
						break;
					}
					hash1 = hash[iter].getHash();
				}
				else {// hash1 > hash2
					b_only.add(op.hash[iter2]);
					++iter2;
					if (iter2 == enditer2) {
						break;
					}
					hash2 = op.hash[iter2].getHash();
				}
			}
			buf.append("dotproduct=").append(res).append('\n');
			buf.append("intersect=").append(intersectcount).append('\n');
			res /= (length * op.length);
		}
		while (iter != enditer) {
			a_only.add(hash[iter]);
			++iter;
		}
		while (iter2 != enditer2) {
			b_only.add(op.hash[iter2]);
			++iter2;
		}
		writeOnlyList(a_only, buf);
		buf.append('\n');
		writeBothList(ab_both, buf);
		buf.append('\n');
		writeOnlyList(b_only, buf);
		return res;
	}
Assuming -feature- is sorted and -hash- is empty, count the features and populate -hash- and -tf-
For every unique feature, look up its idf via -idflookup-
@param feature is the list of sorted hash features
@param wfactory is the WeightFactory used to decide feature weights
@param idflookup is the IDFLookup used to decide relative frequency of individual features
Ghidra/Framework/Generic/src/main/java/generic/lsh/vector/LSHCosineVector.java