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