static int hemdist(bytea *a, bytea *b) { if (ISALLTRUE(a)) { if (ISALLTRUE(b)) return 0; else return SIGLENBIT(b) - bitstringWeight(SIGLEN(b), (uint8 *)VARDATA(b)); } else if (ISALLTRUE(b)) { return SIGLENBIT(a) - bitstringWeight(SIGLEN(a), (uint8 *)VARDATA(a)); } return hemdistsign(a, b); }
static int soergeldist(bytea *a, bytea *b) { if (ISALLTRUE(a)) { if (ISALLTRUE(b)) return 0; else return SIGLENBIT(b) - sizebitvec(b); } else if (ISALLTRUE(b)) { return SIGLENBIT(a) - sizebitvec(a); } return soergeldistsign(a, b); }
static int soergeldist(bytea *a, bytea *b) { double d; if (ISALLTRUE(a)) { if (ISALLTRUE(b)) return 0; else // FIXME shouldn't it be double(sizebitvec(b))/SIGLENBIT(b); ? return SIGLENBIT(b) - bitstringWeight(SIGLEN(b), (uint8 *)VARDATA(b)); } else if (ISALLTRUE(b)) { // FIXME shouldn't it be double(sizebitvec(a))/SIGLENBIT(a); ? return SIGLENBIT(a) - bitstringWeight(SIGLEN(a), (uint8 *)VARDATA(a)); } return (int) floor(10000*soergeldistsign(a, b)); }
static bool rdkit_consistent(GISTENTRY *entry, StrategyNumber strategy, bytea *key, bytea *query) { double nCommon, nQuery, nKey = 0.0; if (ISALLTRUE(query)) elog(ERROR, "Query malformed"); /* * Counts basic numbers, but don't count nKey on inner * page (see comments below) */ nQuery = (double)sizebitvec(query); if (ISALLTRUE(key)) { if (GIST_LEAF(entry)) nKey = (double)SIGLENBIT(query); nCommon = nQuery; } else { int i, cnt = 0; unsigned char *pk = (unsigned char*)VARDATA(key); unsigned char *pq = (unsigned char*)VARDATA(query); if (SIGLEN(key) != SIGLEN(query)) elog(ERROR, "All fingerprints should be the same length"); #ifndef USE_BUILTIN_POPCOUNT for(i=0;i<SIGLEN(key);i++) cnt += number_of_ones[ pk[i] & pq[i] ]; #else unsigned eidx=SIGLEN(key)/sizeof(unsigned int); for(i=0;i<eidx;++i){ cnt += __builtin_popcount(((unsigned int *)pk)[i] & ((unsigned int *)pq)[i]); } for(i=eidx*sizeof(unsigned);i<SIGLEN(key);++i){ cnt += number_of_ones[ pk[i] & pq[i] ]; } #endif nCommon = (double)cnt; if (GIST_LEAF(entry)) nKey = (double)sizebitvec(key); } return calcConsistency(GIST_LEAF(entry), strategy, nCommon, nCommon, nKey, nQuery); }
static bool rdkit_consistent(GISTENTRY *entry, StrategyNumber strategy, bytea *key, bytea *query) { double nCommon, nQuery, nKey = 0.0; if (ISALLTRUE(query)) { elog(ERROR, "Query malformed"); } /* * Counts basic numbers, but don't count nKey on inner * page (see comments below) */ int siglen = SIGLEN(query); uint8 *q = (uint8 *)VARDATA(query); nQuery = (double)bitstringWeight(siglen, q); if (ISALLTRUE(key)) { if (GIST_LEAF(entry)) { nKey = (double)SIGLENBIT(query); } nCommon = nQuery; } else { if (siglen != SIGLEN(key)) { elog(ERROR, "All fingerprints should be the same length"); } uint8 *k = (uint8 *)VARDATA(key); nCommon = bitstringIntersectionWeight(siglen, k, q); if (GIST_LEAF(entry)) { nKey = (double)bitstringWeight(siglen, k); } } return calcConsistency(GIST_LEAF(entry), strategy, nCommon, nCommon, nKey, nQuery); }
Datum gbfp_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); // bytea *query = PG_GETARG_DATA_TYPE_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bytea *key = (bytea*)DatumGetPointer(entry->key); bytea *query; double nCommon, nCommonUp, nCommonDown, nQuery, distance; double nKey = 0.0; fcinfo->flinfo->fn_extra = SearchBitmapFPCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(1), NULL, NULL,&query); if (ISALLTRUE(query)) elog(ERROR, "Query malformed"); /* * Counts basic numbers, but don't count nKey on inner * page (see comments below) */ nQuery = (double)sizebitvec(query); if (ISALLTRUE(key)) { if (GIST_LEAF(entry)) nKey = (double)SIGLENBIT(query); nCommon = nQuery; } else { int i, cnt = 0; unsigned char *pk = (unsigned char*)VARDATA(key), *pq = (unsigned char*)VARDATA(query); if (SIGLEN(key) != SIGLEN(query)) elog(ERROR, "All fingerprints should be the same length"); #ifndef USE_BUILTIN_POPCOUNT for(i=0;i<SIGLEN(key);i++) cnt += number_of_ones[ pk[i] & pq[i] ]; #else unsigned eidx=SIGLEN(key)/sizeof(unsigned int); for(i=0;i<SIGLEN(key)/sizeof(unsigned int);++i){ cnt += __builtin_popcount(((unsigned int *)pk)[i] & ((unsigned int *)pq)[i]); } for(i=eidx*sizeof(unsigned);i<SIGLEN(key);++i){ cnt += number_of_ones[ pk[i] & pq[i] ]; } #endif nCommon = (double)cnt; if (GIST_LEAF(entry)) nKey = (double)sizebitvec(key); } nCommonUp = nCommon; nCommonDown = nCommon; switch(strategy) { case RDKitOrderByTanimotoStrategy: /* * Nsame / (Na + Nb - Nsame) */ if (GIST_LEAF(entry)) { distance = nCommonUp / (nKey + nQuery - nCommonUp); } else { distance = nCommonUp / nQuery; } break; case RDKitOrderByDiceStrategy: /* * 2 * Nsame / (Na + Nb) */ if (GIST_LEAF(entry)) { distance = 2.0 * nCommonUp / (nKey + nQuery); } else { distance = 2.0 * nCommonUp / (nCommonDown + nQuery); } break; default: elog(ERROR,"Unknown strategy: %d", strategy); } PG_RETURN_FLOAT8(1.0 - distance); }