1 // $Id$
2 //
3 //  Copyright (C) 2003-2006 Rational Discovery LLC
4 //
5 //  @@ All Rights Reserved @@
6 //  This file is part of the RDKit.
7 //  The contents are covered by the terms of the BSD license
8 //  which is included in the file license.txt, found at the root
9 //  of the RDKit source tree.
10 //
11 #include <RDGeneral/export.h>
12 #ifndef __RD_METRICMATRIXCAL_H__
13 #define __RD_METRICMATRIXCAL_H__
14 
15 #include "MetricFuncs.h"
16 #include <RDGeneral/Invariant.h>
17 
18 namespace RDDataManip {
19 
20 /*! \brief A generic metric matrix calculator (e.g similarity matrix or
21  *         distance matrix)
22  *
23  *  This templated class needs some explanation
24  *    vectType is a container that can support [] operator
25  *    entryType is the type of entry that is returned by the [] operator
26  *  Examples of the container include PySequenceHolder which is wrapper around
27  *  a python sequence objects like lists and tuples.
28  *  Examples of the entryType include a sequence of double, floats, and
29  *ExplicitBitVects
30  *
31  */
32 template <class vectType, class entryType>
33 class MetricMatrixCalc {
34  public:
35   /*! \brief Default Constructor
36    *
37    */
MetricMatrixCalc()38   MetricMatrixCalc(){};
39 
40   /*! \brief Set the metric function
41    *
42    * Set the pointer to the mertic funvtion to be used by the metric calculator
43    *
44    * ARGUMENTS:
45    *
46    *  mFunc - pointer to the metric function
47    */
setMetricFunc(double (* mFunc)(const entryType &,const entryType &,unsigned int))48   void setMetricFunc(double (*mFunc)(const entryType &, const entryType &,
49                                      unsigned int)) {
50     dp_metricFunc = mFunc;
51   }
52 
53   /*! \brief The calculator function
54    *
55    * ARGUMENTS:
56    *
57    *  descrips - vectType container with a entryType for each item
58    *  nItems - the number of item in the descripts.
59    *           In several cases this argument is irrelvant since vectType
60    *probably supports
61    *           a size() member function, But we would like this interface to
62    *take for example
63    *           a double** and correctly parse the row and columns.
64    *  dim - the dimension of the sequences
65    *  distMat - pointer to an array to write the distance matrix to
66    *            it is assumed that the right sized array has already be
67    *allocated.
68    *
69    * FIX: we can probably make this function create the correct sized distMat
70    *and return
71    * it to the caller, but when pushing he result out to a python array not sure
72    *how to
73    * avoid copy the entire distance matrix in that case
74    *
75    * RETURNS:
76    *
77    *  pointer to a 1D array of doubles. Only the lower triangle elements are
78    *  included in the array
79    */
calcMetricMatrix(const vectType & descripts,unsigned int nItems,unsigned int dim,double * distMat)80   void calcMetricMatrix(const vectType &descripts, unsigned int nItems,
81                         unsigned int dim, double *distMat) {
82     CHECK_INVARIANT(distMat, "invalid pointer to a distance matix");
83 
84     for (unsigned int i = 1; i < nItems; i++) {
85       unsigned int itab = i * (i - 1) / 2;
86       for (unsigned int j = 0; j < i; j++) {
87         distMat[itab + j] = dp_metricFunc(descripts[i], descripts[j], dim);
88       }
89     }
90   };
91 
92  private:
93   // pointer to the metric function
94   /*! \brief pointer to the metric function
95    *
96    * In several cases the last argument 'dim' should be irrelevant,
97    * For example when entryType is a bit vector the size is of the vector
98    * or the dimension can be obtained by asking the bit vector itself. However
99    * we woul like this interface to support other containers lines double*
100    * in which case the 'dim' value is useful in cumputing the metric.
101    */
102   double (*dp_metricFunc)(const entryType &, const entryType &, unsigned int);
103 };
104 };  // namespace RDDataManip
105 
106 #endif
107