Added halfvec_spherical_distance function [skip ci]

This commit is contained in:
Andrew Kane
2024-04-11 13:52:59 -07:00
parent 245bac5e8e
commit bd52ed29e0
3 changed files with 32 additions and 0 deletions

View File

@@ -86,6 +86,9 @@ CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
CREATE FUNCTION halfvec_negative_inner_product(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION halfvec_spherical_distance(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION halfvec(halfvec, integer, boolean) RETURNS halfvec
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -381,6 +381,9 @@ CREATE FUNCTION halfvec_l2_squared_distance(halfvec, halfvec) RETURNS float8
CREATE FUNCTION halfvec_negative_inner_product(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION halfvec_spherical_distance(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- halfvec cast functions
CREATE FUNCTION halfvec(halfvec, integer, boolean) RETURNS halfvec

View File

@@ -879,6 +879,32 @@ halfvec_cosine_distance(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(1 - similarity);
}
/*
* Get the distance for spherical k-means
* Currently uses angular distance since needs to satisfy triangle inequality
* Assumes inputs are unit vectors (skips norm)
*/
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_spherical_distance);
Datum
halfvec_spherical_distance(PG_FUNCTION_ARGS)
{
HalfVector *a = PG_GETARG_HALFVEC_P(0);
HalfVector *b = PG_GETARG_HALFVEC_P(1);
double distance;
CheckDims(a, b);
distance = (double) HalfvecInnerProduct(a->dim, a->x, b->x);
/* Prevent NaN with acos with loss of precision */
if (distance > 1)
distance = 1;
else if (distance < -1)
distance = -1;
PG_RETURN_FLOAT8(acos(distance) / M_PI);
}
/*
* Get the L1 distance between two half vectors
*/