12 #ifndef RD_MAXMINPICKER_H 13 #define RD_MAXMINPICKER_H 22 #include <boost/random.hpp> 30 distmatFunctor(
const double *distMat) : dp_distMat(distMat){};
31 double operator()(
unsigned int i,
unsigned int j) {
36 const double *dp_distMat;
76 unsigned int pickSize)
const;
80 unsigned int pickSize,
86 unsigned int pickSize,
88 double &threshold)
const;
128 int seed = -1)
const {
131 if (poolSize < pickSize)
133 distmatFunctor functor(distMat);
134 return this->lazyPick(functor, poolSize, pickSize, firstPicks, seed);
139 unsigned int pickSize)
const {
141 return pick(distMat, poolSize, pickSize, iv);
153 template <
typename T>
155 unsigned int pickSize,
157 int seed,
double &threshold)
const {
160 if (poolSize < pickSize)
165 unsigned int memsize = (
unsigned int)(poolSize *
sizeof(
MaxMinPickInfo));
171 memset(pinfo, 0, memsize);
173 picks.reserve(pickSize);
174 unsigned int picked = 0;
175 unsigned int pick = 0;
178 if (firstPicks.empty()) {
181 typedef boost::uniform_int<> distrib_type;
182 typedef boost::variate_generator<rng_type &, distrib_type> source_type;
184 distrib_type dist(0, poolSize - 1);
186 generator.seed(static_cast<rng_type::result_type>(seed));
188 generator.seed(std::random_device()());
190 source_type randomSource(generator, dist);
191 pick = randomSource();
193 picks.push_back(pick);
195 pinfo[pick].
picks = 1;
199 for (RDKit::INT_VECT::const_iterator pIdx = firstPicks.begin();
200 pIdx != firstPicks.end(); ++pIdx) {
201 pick =
static_cast<unsigned int>(*pIdx);
202 if (pick >= poolSize) {
206 picks.push_back(pick);
207 pinfo[pick].
picks = 1;
212 if (picked >= pickSize) {
218 unsigned int pool_list = 0;
219 unsigned int *prev = &pool_list;
221 for (
unsigned int i = 0; i < poolSize; i++)
222 if (pinfo[i].picks == 0) {
224 prev = &pinfo[i].
next;
228 unsigned int poolIdx;
229 unsigned int pickIdx;
236 pinfo[poolIdx].
dist_bound = func(poolIdx, pickIdx);
237 pinfo[poolIdx].
picks = 1;
238 prev = &pinfo[poolIdx].
next;
239 }
while (*prev != 0);
242 double maxOFmin = -1.0;
243 double tmpThreshold = -1.0;
244 while (picked < pickSize) {
245 unsigned int *pick_prev = 0;
251 if (minTOi > maxOFmin) {
252 unsigned int pi = pinfo[poolIdx].
picks;
253 while (pi < picked) {
254 unsigned int picki = picks[pi];
256 double dist = func(poolIdx, picki);
258 if (dist <= minTOi) {
260 if (minTOi <= maxOFmin)
break;
264 pinfo[poolIdx].
picks = pi;
265 if (minTOi > maxOFmin) {
271 prev = &pinfo[poolIdx].
next;
272 }
while (*prev != 0);
275 if (threshold >= 0.0 && maxOFmin < threshold)
break;
276 tmpThreshold = maxOFmin;
278 *pick_prev = pinfo[pick].
next;
279 picks.push_back(pick);
283 threshold = tmpThreshold;
288 template <
typename T>
290 unsigned int pickSize,
293 double threshold = -1.0;
298 template <
typename T>
300 unsigned int pickSize)
const {
302 double threshold = -1.0;
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...