PageRenderTime 3ms CodeModel.GetById 38ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/fingerprint/src/fpdistance.c

http://github.com/rajarshi/cdkr
C | 71 lines | 54 code | 7 blank | 10 comment | 26 complexity | 7afe32c102f466fbc046191637bc6229 MD5 | raw file
 1#include <math.h>
 2
 3#define X(_m,_i,_j,_nrow) _m[ _i + _nrow * _j ]
 4
 5#define METRIC_TANIMOTO       1
 6#define METRIC_EUCLIDEAN      2
 7
 8double d_tanimoto(double*,double*,int);
 9double d_euclidean(double*,double*,int);
10
11void m_tanimoto(double *m, int *nrow, double *ret) {
12  int i,j;
13  for (i = 0; i < *nrow; i++) {
14    for (j = i+1; j < *nrow; j++) {
15      double mij = X(m, i,j, *nrow);
16      double mii = X(m, i,i, *nrow);
17      double mjj = X(m, j,j, *nrow);
18      X(ret, i, j, *nrow) = X(ret, j, i, *nrow) = mij / (mii+mjj-mij);
19    }
20  }
21  return;
22}
23
24/**
25fp1 and fp2 should be an array of 1's and 0's, of
26length equal to the size of the fingerprint
27**/
28void fpdistance(double *fp1, double *fp2, int *nbit, int *metric, double *ret) {
29  double r = 0.0;
30  switch(*metric) {
31  case METRIC_TANIMOTO:
32    r = d_tanimoto(fp1, fp2, *nbit);
33    break;
34  case METRIC_EUCLIDEAN:
35    r = d_euclidean(fp1, fp2, *nbit);
36  }
37  *ret = r;
38  return;
39}
40
41/**
42http://www.daylight.com/dayhtml/doc/theory/theory.finger.html
43**/
44double d_tanimoto(double *fp1, double *fp2, int nbit) {
45  int i;
46  int nc = 0;
47  int na = 0;
48  int nb = 0;
49  if (nbit <= 0) return(-1.0);
50  for (i = 0; i < nbit; i++) {
51    if (fp1[i] == 1 && fp2[i] == 1) nc++;
52    if (fp1[i] == 1 && fp2[i] == 0) na++;
53    if (fp2[i] == 1 && fp1[i] == 0) nb++;
54  }
55  return ((double) nc) / (double) (na + nb + nc);
56}
57
58/**
59http://www.daylight.com/dayhtml/doc/theory/theory.finger.html
60**/
61double d_euclidean(double *fp1, double *fp2, int nbit) {
62  int i;
63  int nc = 0;
64  int nd = 0;
65  if (nbit <= 0) return(-1.0);
66  for (i = 0; i < nbit; i++) {
67    if (fp1[i] == 1 && fp2[i] == 1) nc++;
68    if (fp1[i] == 0 && fp2[i] == 0) nd++;
69  }
70  return sqrt(((double) nc + (double) nd) / (double) nbit);
71}