mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-10 06:40:57 +08:00
Added element-wise multiplication for vectors
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
- Added support for parallel index builds
|
- Added support for parallel index builds
|
||||||
- Added `l1_distance` function
|
- Added `l1_distance` function
|
||||||
|
- Added element-wise multiplication for vectors
|
||||||
|
|
||||||
## 0.4.4 (2023-06-12)
|
## 0.4.4 (2023-06-12)
|
||||||
|
|
||||||
|
|||||||
@@ -343,6 +343,7 @@ Operator | Description
|
|||||||
--- | ---
|
--- | ---
|
||||||
\+ | element-wise addition
|
\+ | element-wise addition
|
||||||
\- | element-wise subtraction
|
\- | element-wise subtraction
|
||||||
|
\* | element-wise multiplication [unreleased]
|
||||||
<-> | Euclidean distance
|
<-> | Euclidean distance
|
||||||
<#> | negative inner product
|
<#> | negative inner product
|
||||||
<=> | cosine distance
|
<=> | cosine distance
|
||||||
|
|||||||
@@ -3,3 +3,11 @@
|
|||||||
|
|
||||||
CREATE FUNCTION l1_distance(vector, vector) RETURNS float8
|
CREATE FUNCTION l1_distance(vector, vector) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_mul(vector, vector) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE OPERATOR * (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_mul,
|
||||||
|
COMMUTATOR = *
|
||||||
|
);
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ CREATE FUNCTION vector_add(vector, vector) RETURNS vector
|
|||||||
CREATE FUNCTION vector_sub(vector, vector) RETURNS vector
|
CREATE FUNCTION vector_sub(vector, vector) RETURNS vector
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
|
CREATE FUNCTION vector_mul(vector, vector) RETURNS vector
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
|
||||||
-- private functions
|
-- private functions
|
||||||
|
|
||||||
CREATE FUNCTION vector_lt(vector, vector) RETURNS bool
|
CREATE FUNCTION vector_lt(vector, vector) RETURNS bool
|
||||||
@@ -174,6 +177,11 @@ CREATE OPERATOR - (
|
|||||||
COMMUTATOR = -
|
COMMUTATOR = -
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR * (
|
||||||
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_mul,
|
||||||
|
COMMUTATOR = *
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR < (
|
CREATE OPERATOR < (
|
||||||
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_lt,
|
LEFTARG = vector, RIGHTARG = vector, PROCEDURE = vector_lt,
|
||||||
COMMUTATOR = > , NEGATOR = >= ,
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
|
|||||||
44
src/vector.c
44
src/vector.c
@@ -125,6 +125,14 @@ float_overflow_error(void)
|
|||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("value out of range: overflow")));
|
errmsg("value out of range: overflow")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pg_noinline void
|
||||||
|
float_underflow_error(void)
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("value out of range: underflow")));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -759,6 +767,42 @@ vector_sub(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiply vectors
|
||||||
|
*/
|
||||||
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_mul);
|
||||||
|
Datum
|
||||||
|
vector_mul(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
|
Vector *result;
|
||||||
|
float *rx;
|
||||||
|
|
||||||
|
CheckDims(a, b);
|
||||||
|
|
||||||
|
result = InitVector(a->dim);
|
||||||
|
rx = result->x;
|
||||||
|
|
||||||
|
/* Auto-vectorized */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
rx[i] = ax[i] * bx[i];
|
||||||
|
|
||||||
|
/* Check for overflow and underflow */
|
||||||
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
{
|
||||||
|
if (isinf(rx[i]))
|
||||||
|
float_overflow_error();
|
||||||
|
|
||||||
|
if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0))
|
||||||
|
float_underflow_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
PG_RETURN_POINTER(result);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal helper to compare vectors
|
* Internal helper to compare vectors
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ SELECT '[1,2,3]'::vector - '[4,5,6]';
|
|||||||
|
|
||||||
SELECT '[-3e38]'::vector - '[3e38]';
|
SELECT '[-3e38]'::vector - '[3e38]';
|
||||||
ERROR: value out of range: overflow
|
ERROR: value out of range: overflow
|
||||||
|
SELECT '[1,2,3]'::vector * '[4,5,6]';
|
||||||
|
?column?
|
||||||
|
-----------
|
||||||
|
[4,10,18]
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '[1e37]'::vector * '[1e37]';
|
||||||
|
ERROR: value out of range: overflow
|
||||||
|
SELECT '[1e-37]'::vector * '[1e-37]';
|
||||||
|
ERROR: value out of range: underflow
|
||||||
SELECT vector_dims('[1,2,3]');
|
SELECT vector_dims('[1,2,3]');
|
||||||
vector_dims
|
vector_dims
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ SELECT '[1,2,3]'::vector + '[4,5,6]';
|
|||||||
SELECT '[3e38]'::vector + '[3e38]';
|
SELECT '[3e38]'::vector + '[3e38]';
|
||||||
SELECT '[1,2,3]'::vector - '[4,5,6]';
|
SELECT '[1,2,3]'::vector - '[4,5,6]';
|
||||||
SELECT '[-3e38]'::vector - '[3e38]';
|
SELECT '[-3e38]'::vector - '[3e38]';
|
||||||
|
SELECT '[1,2,3]'::vector * '[4,5,6]';
|
||||||
|
SELECT '[1e37]'::vector * '[1e37]';
|
||||||
|
SELECT '[1e-37]'::vector * '[1e-37]';
|
||||||
|
|
||||||
SELECT vector_dims('[1,2,3]');
|
SELECT vector_dims('[1,2,3]');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user