12 #ifndef RD_MAXMINPICKER_H 13 #define RD_MAXMINPICKER_H 22 #include <boost/random.hpp> 29 distmatFunctor(
const double *distMat) : dp_distMat(distMat){};
30 double operator()(
unsigned int i,
unsigned int j) {
35 const double *dp_distMat;
73 unsigned int pickSize)
const;
77 unsigned int pickSize,
83 unsigned int pickSize,
85 double &threshold)
const;
123 int seed = -1)
const {
126 if (poolSize < pickSize)
128 distmatFunctor functor(distMat);
129 return this->lazyPick(functor, poolSize, pickSize, firstPicks, seed);
134 unsigned int pickSize)
const {
136 return pick(distMat, poolSize, pickSize, iv);
148 template <
typename T>
150 unsigned int pickSize,
152 int seed,
double &threshold)
const {
155 if (poolSize < pickSize)
160 unsigned int memsize = (
unsigned int)(poolSize *
sizeof(
MaxMinPickInfo));
166 memset(pinfo, 0, memsize);
168 picks.reserve(pickSize);
169 unsigned int picked = 0;
170 unsigned int pick = 0;
173 if (firstPicks.empty()) {
176 typedef boost::uniform_int<> distrib_type;
177 typedef boost::variate_generator<rng_type &, distrib_type> source_type;
178 rng_type generator(42u);
179 distrib_type dist(0, poolSize - 1);
180 source_type randomSource(generator, dist);
181 if (seed > 0) generator.seed(static_cast<rng_type::result_type>(seed));
183 pick = randomSource();
185 picks.push_back(pick);
187 pinfo[pick].
picks = 1;
191 for (RDKit::INT_VECT::const_iterator pIdx = firstPicks.begin();
192 pIdx != firstPicks.end(); ++pIdx) {
193 pick =
static_cast<unsigned int>(*pIdx);
194 if (pick >= poolSize) {
198 picks.push_back(pick);
199 pinfo[pick].
picks = 1;
204 if (picked >= pickSize) {
210 unsigned int pool_list = 0;
211 unsigned int *prev = &pool_list;
213 for (
unsigned int i = 0; i < poolSize; i++)
214 if (pinfo[i].picks == 0) {
216 prev = &pinfo[i].
next;
220 unsigned int poolIdx;
221 unsigned int pickIdx;
228 pinfo[poolIdx].
dist_bound = func(poolIdx, pickIdx);
229 pinfo[poolIdx].
picks = 1;
230 prev = &pinfo[poolIdx].
next;
231 }
while (*prev != 0);
234 double maxOFmin = -1.0;
235 double tmpThreshold = -1.0;
236 while (picked < pickSize) {
237 unsigned int *pick_prev = 0;
243 if (minTOi > maxOFmin) {
244 unsigned int pi = pinfo[poolIdx].
picks;
245 while (pi < picked) {
246 unsigned int picki = picks[pi];
248 double dist = func(poolIdx, picki);
250 if (dist <= minTOi) {
252 if (minTOi <= maxOFmin)
break;
256 pinfo[poolIdx].
picks = pi;
257 if (minTOi > maxOFmin) {
263 prev = &pinfo[poolIdx].
next;
264 }
while (*prev != 0);
267 if (threshold >= 0.0 && maxOFmin < threshold)
break;
268 tmpThreshold = maxOFmin;
270 *pick_prev = pinfo[pick].
next;
271 picks.push_back(pick);
275 threshold = tmpThreshold;
280 template <
typename T>
282 unsigned int pickSize,
285 double threshold = -1.0;
290 template <
typename T>
292 unsigned int pickSize)
const {
294 double threshold = -1.0;
std::list< int > INT_LIST
boost::minstd_rand rng_type
#define CHECK_INVARIANT(expr, mess)
#define RDKIT_SIMDIVPICKERS_EXPORT
RDKit::INT_VECT lazyPick(T &func, unsigned int poolSize, unsigned int pickSize) const
Contains the implementation for a lazy MaxMin diversity picker.
std::vector< int > INT_VECT
RDKit::INT_VECT pick(const double *distMat, unsigned int poolSize, unsigned int pickSize) const
Implements the MaxMin algorithm for picking a subset of item from a pool.
RDKit::INT_VECT pick(const double *distMat, unsigned int poolSize, unsigned int pickSize, RDKit::INT_VECT firstPicks, int seed=-1) const
Contains the implementation for the MaxMin diversity picker.
MaxMinPicker()
Default Constructor.
RDKIT_SIMDIVPICKERS_EXPORT double getDistFromLTM(const double *distMat, unsigned int i, unsigned int j)
function to lookup distance from 1D lower triangular distance matrix
Class to allow us to throw a ValueError from C++ and have it make it back to Python.
Abstract base class to do perform item picking (typically molecules) using a distance matrix...