Compare commits

..

2 Commits

Author SHA1 Message Date
Andrew Kane
5425dd2357 Fixed warning 2024-04-03 15:17:52 -07:00
Andrew Kane
7ca7a64dbb Added subvector function for sparsevec 2024-04-03 15:10:06 -07:00
7 changed files with 112 additions and 18 deletions

View File

@@ -777,7 +777,6 @@ Function | Description | Added
cosine_distance(halfvec, halfvec) → double precision | cosine distance | unreleased
inner_product(halfvec, halfvec) → double precision | inner product | unreleased
l2_distance(halfvec, halfvec) → double precision | Euclidean distance | unreleased
l2_norm(halfvec) → double precision | Euclidean norm | unreleased
l1_distance(halfvec, halfvec) → double precision | taxicab distance | unreleased
quantize_binary(halfvec) → bit | quantize | unreleased
subvector(halfvec, integer, integer) → halfvec | subvector | unreleased
@@ -819,7 +818,6 @@ Function | Description | Added
cosine_distance(sparsevec, sparsevec) → double precision | cosine distance | unreleased
inner_product(sparsevec, sparsevec) → double precision | inner product | unreleased
l2_distance(sparsevec, sparsevec) → double precision | Euclidean distance | unreleased
l2_norm(sparsevec) → double precision | Euclidean norm | unreleased
l1_distance(sparsevec, sparsevec) → double precision | taxicab distance | unreleased
## Installation Notes - Linux and Mac

View File

@@ -71,8 +71,8 @@ CREATE FUNCTION cosine_distance(halfvec, halfvec) RETURNS float8
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION l2_norm(halfvec) RETURNS float8
AS 'MODULE_PATHNAME', 'halfvec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
@@ -151,7 +151,7 @@ CREATE OPERATOR CLASS halfvec_cosine_ops
FOR TYPE halfvec USING hnsw AS
OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops,
FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec),
FUNCTION 2 l2_norm(halfvec);
FUNCTION 2 halfvec_norm(halfvec);
CREATE FUNCTION halfvec_to_vector(halfvec, integer, boolean) RETURNS vector
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
@@ -200,8 +200,11 @@ CREATE FUNCTION inner_product(sparsevec, sparsevec) RETURNS float8
CREATE FUNCTION cosine_distance(sparsevec, sparsevec) RETURNS float8
AS 'MODULE_PATHNAME', 'sparsevec_cosine_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION l2_norm(sparsevec) RETURNS float8
AS 'MODULE_PATHNAME', 'sparsevec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION sparsevec_norm(sparsevec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION subvector(sparsevec, int, int) RETURNS sparsevec
AS 'MODULE_PATHNAME', 'sparsevec_subvector' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION sparsevec_l2_squared_distance(sparsevec, sparsevec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
@@ -256,4 +259,4 @@ CREATE OPERATOR CLASS sparsevec_cosine_ops
FOR TYPE sparsevec USING hnsw AS
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
FUNCTION 2 l2_norm(sparsevec);
FUNCTION 2 sparsevec_norm(sparsevec);

View File

@@ -364,8 +364,8 @@ CREATE FUNCTION cosine_distance(halfvec, halfvec) RETURNS float8
CREATE FUNCTION l1_distance(halfvec, halfvec) RETURNS float8
AS 'MODULE_PATHNAME', 'halfvec_l1_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION l2_norm(halfvec) RETURNS float8
AS 'MODULE_PATHNAME', 'halfvec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION halfvec_norm(halfvec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION quantize_binary(halfvec) RETURNS bit
AS 'MODULE_PATHNAME', 'halfvec_quantize_binary' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
@@ -454,7 +454,7 @@ CREATE OPERATOR CLASS halfvec_cosine_ops
FOR TYPE halfvec USING hnsw AS
OPERATOR 1 <=> (halfvec, halfvec) FOR ORDER BY float_ops,
FUNCTION 1 halfvec_negative_inner_product(halfvec, halfvec),
FUNCTION 2 l2_norm(halfvec);
FUNCTION 2 halfvec_norm(halfvec);
-- extension casts
@@ -509,8 +509,11 @@ CREATE FUNCTION inner_product(sparsevec, sparsevec) RETURNS float8
CREATE FUNCTION cosine_distance(sparsevec, sparsevec) RETURNS float8
AS 'MODULE_PATHNAME', 'sparsevec_cosine_distance' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION l2_norm(sparsevec) RETURNS float8
AS 'MODULE_PATHNAME', 'sparsevec_l2_norm' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION sparsevec_norm(sparsevec) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION subvector(sparsevec, int, int) RETURNS sparsevec
AS 'MODULE_PATHNAME', 'sparsevec_subvector' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- sparsevec private functions
@@ -575,4 +578,4 @@ CREATE OPERATOR CLASS sparsevec_cosine_ops
FOR TYPE sparsevec USING hnsw AS
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
FUNCTION 2 l2_norm(sparsevec);
FUNCTION 2 sparsevec_norm(sparsevec);

View File

@@ -950,9 +950,9 @@ halfvec_l1_distance(PG_FUNCTION_ARGS)
/*
* Get the L2 norm of a half vector
*/
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_norm);
PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_norm);
Datum
halfvec_l2_norm(PG_FUNCTION_ARGS)
halfvec_norm(PG_FUNCTION_ARGS)
{
HalfVector *a = PG_GETARG_HALFVEC_P(0);
half *ax = a->x;

View File

@@ -762,9 +762,9 @@ sparsevec_cosine_distance(PG_FUNCTION_ARGS)
/*
* Get the L2 norm of a sparse vector
*/
PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_norm);
PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_norm);
Datum
sparsevec_l2_norm(PG_FUNCTION_ARGS)
sparsevec_norm(PG_FUNCTION_ARGS)
{
SparseVector *a = PG_GETARG_SPARSEVEC_P(0);
float *ax = SPARSEVEC_VALUES(a);
@@ -776,3 +776,55 @@ sparsevec_l2_norm(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(sqrt(norm));
}
/*
* Get a subvector
*/
PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_subvector);
Datum
sparsevec_subvector(PG_FUNCTION_ARGS)
{
SparseVector *a = PG_GETARG_SPARSEVEC_P(0);
int32 start = PG_GETARG_INT32(1);
int32 count = PG_GETARG_INT32(2);
int32 end = start + count;
float *ax = SPARSEVEC_VALUES(a);
SparseVector *result;
float *rx;
int dim;
int nnz = 0;
int startIndex;
/* Indexing starts at 1, like substring */
if (start < 1)
start = 1;
if (end > a->dim)
end = a->dim + 1;
dim = end - start;
CheckDim(dim);
for (startIndex = 0; startIndex < a->nnz; startIndex++)
{
if (a->indices[startIndex] >= start - 1)
break;
}
for (int i = startIndex; i < a->nnz; i++)
{
if (a->indices[i] < end - 1)
nnz++;
}
result = InitSparseVector(dim, nnz);
rx = SPARSEVEC_VALUES(result);
for (int i = 0; i < nnz; i++)
{
result->indices[i] = a->indices[startIndex + i];
rx[i] = ax[startIndex + i];
}
PG_RETURN_POINTER(result);
}

View File

@@ -60,3 +60,33 @@ SELECT cosine_distance('{}/1'::sparsevec, '{}/1');
SELECT cosine_distance('{0:1}/2'::sparsevec, '{0:1}/3');
ERROR: different sparsevec dimensions 2 and 3
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 1, 3);
subvector
-----------------
{0:1,1:2,2:3}/3
(1 row)
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, 2);
subvector
-------------
{2:3,3:4}/2
(1 row)
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, -1, 3);
subvector
-----------
{0:1}/1
(1 row)
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, 9);
subvector
-----------------
{2:3,3:4,4:5}/3
(1 row)
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 1, 0);
ERROR: sparsevec must have at least 1 dimension
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, -1);
ERROR: sparsevec must have at least 1 dimension
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, -1, 2);
ERROR: sparsevec must have at least 1 dimension

View File

@@ -11,3 +11,11 @@ SELECT cosine_distance('{0:1,1:1}/2'::sparsevec, '{0:-1,1:-1}/2');
SELECT cosine_distance('{0:1}/2'::sparsevec, '{1:2}/2');
SELECT cosine_distance('{}/1'::sparsevec, '{}/1');
SELECT cosine_distance('{0:1}/2'::sparsevec, '{0:1}/3');
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 1, 3);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, 2);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, -1, 3);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, 9);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 1, 0);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, 3, -1);
SELECT subvector('{0:1,1:2,2:3,3:4,4:5}/5'::sparsevec, -1, 2);