mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-14 16:46:54 +08:00
Added L2 distance [skip ci]
This commit is contained in:
@@ -27,6 +27,14 @@ CREATE TYPE minivec (
|
|||||||
STORAGE = external
|
STORAGE = external
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE FUNCTION l2_distance(minivec, minivec) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME', 'minivec_l2_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE OPERATOR <-> (
|
||||||
|
LEFTARG = minivec, RIGHTARG = minivec, PROCEDURE = l2_distance,
|
||||||
|
COMMUTATOR = '<->'
|
||||||
|
);
|
||||||
|
|
||||||
CREATE FUNCTION array_to_sparsevec(integer[], integer, boolean) RETURNS sparsevec
|
CREATE FUNCTION array_to_sparsevec(integer[], integer, boolean) RETURNS sparsevec
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
|||||||
@@ -675,6 +675,18 @@ CREATE TYPE minivec (
|
|||||||
STORAGE = external
|
STORAGE = external
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- minivec functions
|
||||||
|
|
||||||
|
CREATE FUNCTION l2_distance(minivec, minivec) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME', 'minivec_l2_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- minivec operators
|
||||||
|
|
||||||
|
CREATE OPERATOR <-> (
|
||||||
|
LEFTARG = minivec, RIGHTARG = minivec, PROCEDURE = l2_distance,
|
||||||
|
COMMUTATOR = '<->'
|
||||||
|
);
|
||||||
|
|
||||||
-- bit functions
|
-- bit functions
|
||||||
|
|
||||||
CREATE FUNCTION hamming_distance(bit, bit) RETURNS float8
|
CREATE FUNCTION hamming_distance(bit, bit) RETURNS float8
|
||||||
|
|||||||
@@ -17,6 +17,18 @@
|
|||||||
#include "utils/numeric.h"
|
#include "utils/numeric.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure same dimensions
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
CheckDims(MiniVector * a, MiniVector * b)
|
||||||
|
{
|
||||||
|
if (a->dim != b->dim)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATA_EXCEPTION),
|
||||||
|
errmsg("different minivec dimensions %d and %d", a->dim, b->dim)));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure expected dimensions
|
* Ensure expected dimensions
|
||||||
*/
|
*/
|
||||||
@@ -334,3 +346,34 @@ minivec_send(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
MinivecL2SquaredDistance(int dim, fp8 * ax, fp8 * bx)
|
||||||
|
{
|
||||||
|
float distance = 0.0;
|
||||||
|
|
||||||
|
/* Auto-vectorized */
|
||||||
|
for (int i = 0; i < dim; i++)
|
||||||
|
{
|
||||||
|
float diff = Fp8ToFloat4(ax[i]) - Fp8ToFloat4(bx[i]);
|
||||||
|
|
||||||
|
distance += diff * diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the L2 distance between fp8 vectors
|
||||||
|
*/
|
||||||
|
FUNCTION_PREFIX PG_FUNCTION_INFO_V1(minivec_l2_distance);
|
||||||
|
Datum
|
||||||
|
minivec_l2_distance(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
MiniVector *a = PG_GETARG_MINIVEC_P(0);
|
||||||
|
MiniVector *b = PG_GETARG_MINIVEC_P(1);
|
||||||
|
|
||||||
|
CheckDims(a, b);
|
||||||
|
|
||||||
|
PG_RETURN_FLOAT8(sqrt((double) MinivecL2SquaredDistance(a->dim, a->x, b->x)));
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,3 +168,29 @@ SELECT '{"[1,2,3]"}'::minivec(2)[];
|
|||||||
{"[1,2,3]"}
|
{"[1,2,3]"}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT l2_distance('[0,0]'::minivec, '[3,4]');
|
||||||
|
l2_distance
|
||||||
|
-------------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT l2_distance('[0,0]'::minivec, '[0,1]');
|
||||||
|
l2_distance
|
||||||
|
-------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT l2_distance('[1,2]'::minivec, '[3]');
|
||||||
|
ERROR: different minivec dimensions 2 and 1
|
||||||
|
SELECT l2_distance('[1,1,1,1,1,1,1,1,1]'::minivec, '[1,1,1,1,1,1,1,4,5]');
|
||||||
|
l2_distance
|
||||||
|
-------------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[0,0]'::minivec <-> '[3,4]';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
|||||||
@@ -36,3 +36,9 @@ SELECT '[1,2,3]'::minivec(16001);
|
|||||||
|
|
||||||
SELECT unnest('{"[1,2,3]", "[4,5,6]"}'::minivec[]);
|
SELECT unnest('{"[1,2,3]", "[4,5,6]"}'::minivec[]);
|
||||||
SELECT '{"[1,2,3]"}'::minivec(2)[];
|
SELECT '{"[1,2,3]"}'::minivec(2)[];
|
||||||
|
|
||||||
|
SELECT l2_distance('[0,0]'::minivec, '[3,4]');
|
||||||
|
SELECT l2_distance('[0,0]'::minivec, '[0,1]');
|
||||||
|
SELECT l2_distance('[1,2]'::minivec, '[3]');
|
||||||
|
SELECT l2_distance('[1,1,1,1,1,1,1,1,1]'::minivec, '[1,1,1,1,1,1,1,4,5]');
|
||||||
|
SELECT '[0,0]'::minivec <-> '[3,4]';
|
||||||
|
|||||||
Reference in New Issue
Block a user