mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-15 09:06:56 +08:00
Added experimental support for Windows (including auto-vectorization) - closes #49
This commit is contained in:
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@@ -42,3 +42,16 @@ jobs:
|
|||||||
wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_14_5.tar.gz
|
wget -q https://github.com/postgres/postgres/archive/refs/tags/REL_14_5.tar.gz
|
||||||
tar xf REL_14_5.tar.gz
|
tar xf REL_14_5.tar.gz
|
||||||
make prove_installcheck PROVE=prove PROVE_FLAGS="-I ./postgres-REL_14_5/src/test/perl" PERL5LIB="/Users/runner/perl5/lib/perl5"
|
make prove_installcheck PROVE=prove PROVE_FLAGS="-I ./postgres-REL_14_5/src/test/perl" PERL5LIB="/Users/runner/perl5/lib/perl5"
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ankane/setup-postgres@v1
|
||||||
|
with:
|
||||||
|
postgres-version: 14
|
||||||
|
- run: |
|
||||||
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
|
nmake /NOLOGO /F Makefile.win
|
||||||
|
nmake /NOLOGO /F Makefile.win install
|
||||||
|
nmake /NOLOGO /F Makefile.win installcheck
|
||||||
|
shell: cmd
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
- Changed text representation for vector elements to match `real`
|
- Changed text representation for vector elements to match `real`
|
||||||
- Improved accuracy of text parsing for certain inputs
|
- Improved accuracy of text parsing for certain inputs
|
||||||
|
- Added experimental support for Windows
|
||||||
|
|
||||||
## 0.3.2 (2022-11-22)
|
## 0.3.2 (2022-11-22)
|
||||||
|
|
||||||
|
|||||||
65
Makefile.win
Normal file
65
Makefile.win
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
EXTENSION = vector
|
||||||
|
EXTVERSION = 0.3.2
|
||||||
|
|
||||||
|
OBJS = src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\vector.obj
|
||||||
|
|
||||||
|
# For /arch flags
|
||||||
|
# https://learn.microsoft.com/en-us/cpp/build/reference/arch-minimum-cpu-architecture
|
||||||
|
OPTFLAGS =
|
||||||
|
|
||||||
|
# For auto-vectorization:
|
||||||
|
# - MSVC (needs /O2 /fp:fast) - https://learn.microsoft.com/en-us/cpp/parallel/auto-parallelization-and-auto-vectorization?#auto-vectorizer
|
||||||
|
PG_CFLAGS = $(PG_CFLAGS) $(OPTFLAGS) /O2 /fp:fast
|
||||||
|
|
||||||
|
# Debug MSVC auto-vectorization
|
||||||
|
# https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/vectorizer-and-parallelizer-messages
|
||||||
|
# PG_CFLAGS = $(PG_CFLAGS) /Qvec-report:2
|
||||||
|
|
||||||
|
all: sql\$(EXTENSION)--$(EXTVERSION).sql
|
||||||
|
|
||||||
|
sql\$(EXTENSION)--$(EXTVERSION).sql: sql\$(EXTENSION).sql
|
||||||
|
copy sql\$(EXTENSION).sql $@
|
||||||
|
|
||||||
|
# TODO use pg_config
|
||||||
|
INCLUDEDIR = $(PGROOT)\include
|
||||||
|
INCLUDEDIR_SERVER = $(PGROOT)\include\server
|
||||||
|
LIBDIR = $(PGROOT)\lib
|
||||||
|
PKGLIBDIR = $(PGROOT)\lib
|
||||||
|
SHAREDIR = $(PGROOT)\share
|
||||||
|
|
||||||
|
CFLAGS = /nologo /I"$(INCLUDEDIR_SERVER)\port\win32_msvc" /I"$(INCLUDEDIR_SERVER)\port\win32" /I"$(INCLUDEDIR_SERVER)" /I"$(INCLUDEDIR)"
|
||||||
|
|
||||||
|
CFLAGS = $(CFLAGS) $(PG_CFLAGS)
|
||||||
|
|
||||||
|
SHLIB = src\$(EXTENSION).dll
|
||||||
|
|
||||||
|
LIBS = "$(LIBDIR)\postgres.lib"
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(CC) $(CFLAGS) /c $< /Fo$@
|
||||||
|
|
||||||
|
$(SHLIB): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(OBJS) $(LIBS) /link /DLL /OUT:$(SHLIB)
|
||||||
|
|
||||||
|
all: $(SHLIB)
|
||||||
|
|
||||||
|
install:
|
||||||
|
copy $(SHLIB) "$(PKGLIBDIR)"
|
||||||
|
copy $(EXTENSION).control "$(SHAREDIR)\extension"
|
||||||
|
copy sql\$(EXTENSION)--*.sql "$(SHAREDIR)\extension"
|
||||||
|
|
||||||
|
# TODO improve
|
||||||
|
installcheck:
|
||||||
|
createdb contrib_regression
|
||||||
|
mkdir -p results
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\btree.sql > results\btree.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\cast.sql > results\cast.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\copy.sql > results\copy.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\functions.sql > results\functions.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\input.sql > results\input.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\ivfflat_cosine.sql > results\ivfflat_cosine.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\ivfflat_ip.sql > results\ivfflat_ip.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\ivfflat_l2.sql > results\ivfflat_l2.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\ivfflat_options.sql > results\ivfflat_options.out 2>&1
|
||||||
|
psql -d contrib_regression -a -q -f test\sql\ivfflat_unlogged.sql > results\ivfflat_unlogged.out 2>&1
|
||||||
|
cat results/*
|
||||||
@@ -164,7 +164,7 @@ ivfflatvalidate(Oid opclassoid)
|
|||||||
*
|
*
|
||||||
* See https://www.postgresql.org/docs/current/index-api.html
|
* See https://www.postgresql.org/docs/current/index-api.html
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(ivfflathandler);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflathandler);
|
||||||
Datum
|
Datum
|
||||||
ivfflathandler(PG_FUNCTION_ARGS)
|
ivfflathandler(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,6 +78,9 @@
|
|||||||
/* Variables */
|
/* Variables */
|
||||||
extern int ivfflat_probes;
|
extern int ivfflat_probes;
|
||||||
|
|
||||||
|
/* Exported functions */
|
||||||
|
PGDLLEXPORT void _PG_init(void);
|
||||||
|
|
||||||
typedef struct VectorArrayData
|
typedef struct VectorArrayData
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
@@ -210,7 +213,6 @@ typedef IvfflatScanOpaqueData * IvfflatScanOpaque;
|
|||||||
#define VectorArraySet(_arr, _offset, _val) (memcpy(VECTOR_ARRAY_OFFSET(_arr, _offset), _val, VECTOR_SIZE(_arr->dim)))
|
#define VectorArraySet(_arr, _offset, _val) (memcpy(VECTOR_ARRAY_OFFSET(_arr, _offset), _val, VECTOR_SIZE(_arr->dim)))
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
void _PG_init(void);
|
|
||||||
VectorArray VectorArrayInit(int maxlen, int dimensions);
|
VectorArray VectorArrayInit(int maxlen, int dimensions);
|
||||||
void VectorArrayFree(VectorArray arr);
|
void VectorArrayFree(VectorArray arr);
|
||||||
void PrintVectorArray(char *msg, VectorArray arr);
|
void PrintVectorArray(char *msg, VectorArray arr);
|
||||||
|
|||||||
95
src/vector.c
95
src/vector.c
@@ -109,7 +109,7 @@ PrintVector(char *msg, Vector * vector)
|
|||||||
/*
|
/*
|
||||||
* Convert textual representation to internal representation
|
* Convert textual representation to internal representation
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_in);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_in);
|
||||||
Datum
|
Datum
|
||||||
vector_in(PG_FUNCTION_ARGS)
|
vector_in(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -186,7 +186,7 @@ vector_in(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert internal representation to textual representation
|
* Convert internal representation to textual representation
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_out);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_out);
|
||||||
Datum
|
Datum
|
||||||
vector_out(PG_FUNCTION_ARGS)
|
vector_out(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -247,7 +247,7 @@ vector_out(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert type modifier
|
* Convert type modifier
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_typmod_in);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_typmod_in);
|
||||||
Datum
|
Datum
|
||||||
vector_typmod_in(PG_FUNCTION_ARGS)
|
vector_typmod_in(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -278,7 +278,7 @@ vector_typmod_in(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert external binary representation to internal representation
|
* Convert external binary representation to internal representation
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_recv);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_recv);
|
||||||
Datum
|
Datum
|
||||||
vector_recv(PG_FUNCTION_ARGS)
|
vector_recv(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -310,7 +310,7 @@ vector_recv(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert internal representation to the external binary representation
|
* Convert internal representation to the external binary representation
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_send);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_send);
|
||||||
Datum
|
Datum
|
||||||
vector_send(PG_FUNCTION_ARGS)
|
vector_send(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -330,7 +330,7 @@ vector_send(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert vector to vector
|
* Convert vector to vector
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector);
|
||||||
Datum
|
Datum
|
||||||
vector(PG_FUNCTION_ARGS)
|
vector(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -345,7 +345,7 @@ vector(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert array to vector
|
* Convert array to vector
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(array_to_vector);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_vector);
|
||||||
Datum
|
Datum
|
||||||
array_to_vector(PG_FUNCTION_ARGS)
|
array_to_vector(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -403,7 +403,7 @@ array_to_vector(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Convert vector to float4[]
|
* Convert vector to float4[]
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_to_float4);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_float4);
|
||||||
Datum
|
Datum
|
||||||
vector_to_float4(PG_FUNCTION_ARGS)
|
vector_to_float4(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -426,12 +426,14 @@ vector_to_float4(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the L2 distance between vectors
|
* Get the L2 distance between vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(l2_distance);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_distance);
|
||||||
Datum
|
Datum
|
||||||
l2_distance(PG_FUNCTION_ARGS)
|
l2_distance(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
@@ -439,7 +441,7 @@ l2_distance(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
diff = a->x[i] - b->x[i];
|
diff = ax[i] - bx[i];
|
||||||
distance += diff * diff;
|
distance += diff * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,12 +452,14 @@ l2_distance(PG_FUNCTION_ARGS)
|
|||||||
* Get the L2 squared distance between vectors
|
* Get the L2 squared distance between vectors
|
||||||
* This saves a sqrt calculation
|
* This saves a sqrt calculation
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_l2_squared_distance);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_l2_squared_distance);
|
||||||
Datum
|
Datum
|
||||||
vector_l2_squared_distance(PG_FUNCTION_ARGS)
|
vector_l2_squared_distance(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
@@ -463,7 +467,7 @@ vector_l2_squared_distance(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
diff = a->x[i] - b->x[i];
|
diff = ax[i] - bx[i];
|
||||||
distance += diff * diff;
|
distance += diff * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,18 +477,20 @@ vector_l2_squared_distance(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the inner product of two vectors
|
* Get the inner product of two vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(inner_product);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(inner_product);
|
||||||
Datum
|
Datum
|
||||||
inner_product(PG_FUNCTION_ARGS)
|
inner_product(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
|
|
||||||
CheckDims(a, b);
|
CheckDims(a, b);
|
||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
distance += a->x[i] * b->x[i];
|
distance += ax[i] * bx[i];
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(distance);
|
PG_RETURN_FLOAT8(distance);
|
||||||
}
|
}
|
||||||
@@ -492,18 +498,20 @@ inner_product(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the negative inner product of two vectors
|
* Get the negative inner product of two vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_negative_inner_product);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_negative_inner_product);
|
||||||
Datum
|
Datum
|
||||||
vector_negative_inner_product(PG_FUNCTION_ARGS)
|
vector_negative_inner_product(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
|
|
||||||
CheckDims(a, b);
|
CheckDims(a, b);
|
||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
distance += a->x[i] * b->x[i];
|
distance += ax[i] * bx[i];
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(distance * -1);
|
PG_RETURN_FLOAT8(distance * -1);
|
||||||
}
|
}
|
||||||
@@ -511,12 +519,14 @@ vector_negative_inner_product(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the cosine distance between two vectors
|
* Get the cosine distance between two vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(cosine_distance);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(cosine_distance);
|
||||||
Datum
|
Datum
|
||||||
cosine_distance(PG_FUNCTION_ARGS)
|
cosine_distance(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
double norma = 0.0;
|
double norma = 0.0;
|
||||||
double normb = 0.0;
|
double normb = 0.0;
|
||||||
@@ -525,9 +535,9 @@ cosine_distance(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
distance += a->x[i] * b->x[i];
|
distance += ax[i] * bx[i];
|
||||||
norma += a->x[i] * a->x[i];
|
norma += ax[i] * ax[i];
|
||||||
normb += b->x[i] * b->x[i];
|
normb += bx[i] * bx[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(1 - (distance / (sqrt(norma) * sqrt(normb))));
|
PG_RETURN_FLOAT8(1 - (distance / (sqrt(norma) * sqrt(normb))));
|
||||||
@@ -538,7 +548,7 @@ cosine_distance(PG_FUNCTION_ARGS)
|
|||||||
* Currently uses angular distance since needs to satisfy triangle inequality
|
* Currently uses angular distance since needs to satisfy triangle inequality
|
||||||
* Assumes inputs are unit vectors (skips norm)
|
* Assumes inputs are unit vectors (skips norm)
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_spherical_distance);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_spherical_distance);
|
||||||
Datum
|
Datum
|
||||||
vector_spherical_distance(PG_FUNCTION_ARGS)
|
vector_spherical_distance(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -563,7 +573,7 @@ vector_spherical_distance(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the dimensions of a vector
|
* Get the dimensions of a vector
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_dims);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_dims);
|
||||||
Datum
|
Datum
|
||||||
vector_dims(PG_FUNCTION_ARGS)
|
vector_dims(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -575,15 +585,16 @@ vector_dims(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Get the L2 norm of a vector
|
* Get the L2 norm of a vector
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_norm);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_norm);
|
||||||
Datum
|
Datum
|
||||||
vector_norm(PG_FUNCTION_ARGS)
|
vector_norm(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
|
float *ax = a->x;
|
||||||
double norm = 0.0;
|
double norm = 0.0;
|
||||||
|
|
||||||
for (int i = 0; i < a->dim; i++)
|
for (int i = 0; i < a->dim; i++)
|
||||||
norm += a->x[i] * a->x[i];
|
norm += ax[i] * ax[i];
|
||||||
|
|
||||||
PG_RETURN_FLOAT8(sqrt(norm));
|
PG_RETURN_FLOAT8(sqrt(norm));
|
||||||
}
|
}
|
||||||
@@ -591,20 +602,23 @@ vector_norm(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Add vectors
|
* Add vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_add);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_add);
|
||||||
Datum
|
Datum
|
||||||
vector_add(PG_FUNCTION_ARGS)
|
vector_add(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
Vector *result;
|
Vector *result;
|
||||||
int i;
|
float *rx;
|
||||||
|
|
||||||
CheckDims(a, b);
|
CheckDims(a, b);
|
||||||
|
|
||||||
result = InitVector(a->dim);
|
result = InitVector(a->dim);
|
||||||
for (i = 0; i < a->dim; i++)
|
rx = result->x;
|
||||||
result->x[i] = a->x[i] + b->x[i];
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
rx[i] = ax[i] + bx[i];
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@@ -612,20 +626,23 @@ vector_add(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Subtract vectors
|
* Subtract vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_sub);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_sub);
|
||||||
Datum
|
Datum
|
||||||
vector_sub(PG_FUNCTION_ARGS)
|
vector_sub(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Vector *a = PG_GETARG_VECTOR_P(0);
|
Vector *a = PG_GETARG_VECTOR_P(0);
|
||||||
Vector *b = PG_GETARG_VECTOR_P(1);
|
Vector *b = PG_GETARG_VECTOR_P(1);
|
||||||
|
float *ax = a->x;
|
||||||
|
float *bx = b->x;
|
||||||
Vector *result;
|
Vector *result;
|
||||||
int i;
|
float *rx;
|
||||||
|
|
||||||
CheckDims(a, b);
|
CheckDims(a, b);
|
||||||
|
|
||||||
result = InitVector(a->dim);
|
result = InitVector(a->dim);
|
||||||
for (i = 0; i < a->dim; i++)
|
rx = result->x;
|
||||||
result->x[i] = a->x[i] - b->x[i];
|
for (int i = 0, imax = a->dim; i < imax; i++)
|
||||||
|
rx[i] = ax[i] - bx[i];
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@@ -654,7 +671,7 @@ vector_cmp_internal(Vector * a, Vector * b)
|
|||||||
/*
|
/*
|
||||||
* Less than
|
* Less than
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_lt);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_lt);
|
||||||
Datum
|
Datum
|
||||||
vector_lt(PG_FUNCTION_ARGS)
|
vector_lt(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -667,7 +684,7 @@ vector_lt(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Less than or equal
|
* Less than or equal
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_le);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_le);
|
||||||
Datum
|
Datum
|
||||||
vector_le(PG_FUNCTION_ARGS)
|
vector_le(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -680,7 +697,7 @@ vector_le(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Equal
|
* Equal
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_eq);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_eq);
|
||||||
Datum
|
Datum
|
||||||
vector_eq(PG_FUNCTION_ARGS)
|
vector_eq(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -693,7 +710,7 @@ vector_eq(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Not equal
|
* Not equal
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_ne);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ne);
|
||||||
Datum
|
Datum
|
||||||
vector_ne(PG_FUNCTION_ARGS)
|
vector_ne(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -706,7 +723,7 @@ vector_ne(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Greater than or equal
|
* Greater than or equal
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_ge);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ge);
|
||||||
Datum
|
Datum
|
||||||
vector_ge(PG_FUNCTION_ARGS)
|
vector_ge(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -719,7 +736,7 @@ vector_ge(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Greater than
|
* Greater than
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_gt);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_gt);
|
||||||
Datum
|
Datum
|
||||||
vector_gt(PG_FUNCTION_ARGS)
|
vector_gt(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@@ -732,7 +749,7 @@ vector_gt(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Compare vectors
|
* Compare vectors
|
||||||
*/
|
*/
|
||||||
PG_FUNCTION_INFO_V1(vector_cmp);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_cmp);
|
||||||
Datum
|
Datum
|
||||||
vector_cmp(PG_FUNCTION_ARGS)
|
vector_cmp(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user