uint64_t const gfmul64(const uint64_t& i,const uint64_t& j){

__m128i I{};I[0]^=i;

__m128i J{};J[0]^=j;

__m128i M{};M[0]^=0xb000000000000000ull;

__m128i X = _mm_clmulepi64_si128(I,J,0);

__m128i A = _mm_clmulepi64_si128(X,M,0);

__m128i B = _mm_clmulepi64_si128(A,M,0);

return A[0]^A[1]^B[1]^X[0]^X[1];

}

where clmul is fast enough, and rotate_left(h*c1,21)*c1 where it is not, so very similar to what you did, but when rotating instead of shifting one does retain the injective property of the hash.

]]>ab = a . b + a ^ b

Where a ^ b is a plane that both a and b occupy. However, when I do this multiplication I actually get a quaternion that rotates from a to b. So the bivectors resulting from the wedge product seem to be scaled by sin theta. Is that meant to be the case?

]]>I’d love to see an update to this article, now that Google’s implementation is released.

https://github.com/abseil/abseil-cpp/tree/master/absl/container

]]>