Datum bfp_dice_sml_op(PG_FUNCTION_ARGS) { MolBitmapFingerPrint abfp, bbfp; double res; fcinfo->flinfo->fn_extra = SearchBitmapFPCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(0), NULL, &abfp, NULL); fcinfo->flinfo->fn_extra = SearchBitmapFPCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(1), NULL, &bbfp, NULL); res = calcBitmapDiceSml(abfp, bbfp); PG_RETURN_BOOL( res >= getDiceLimit() ); }
bool calcConsistency(bool isLeaf, uint16 strategy, double nCommonUp, double nCommonDown, double nKey, double nQuery) { bool res = false; /* * We don't wish to use RDKit's functions to compute similarity * for two reasons: * - too expensive * - on inner page it will give wrong result, because inner keys * are not a real fingerprints, they are OR-ed all subsequent * fingerprints * * For inner key we should compule maximum possible numerator and * minimum possible denominator to find an upper bound of similarity. * * nCommon and nKey could not become greater on child - so they are * an upper bound of number of common bits and number of set bit * correspondingly. Lower bound of nKey is nCommon. */ switch(strategy) { case RDKitTanimotoStrategy: /* * Nsame / (Na + Nb - Nsame) */ if ( isLeaf ) { if ( nCommonUp / (nKey + nQuery - nCommonUp) >= getTanimotoLimit() ) { res = true; } } else { if ( nCommonUp / nQuery >= getTanimotoLimit() ) { res = true; } } break; case RDKitDiceStrategy: /* * 2 * Nsame / (Na + Nb) */ if ( isLeaf ) { if ( 2.0 * nCommonUp / (nKey + nQuery) >= getDiceLimit() ) { res = true; } } else { if ( 2.0 * nCommonUp / (nCommonDown + nQuery) >= getDiceLimit() ) { res = true; } } break; default: elog(ERROR,"Unknown strategy: %d", strategy); } return res; }