double pickRandomDistMat(const BoundsMatrix &mmat, RDNumeric::SymmMatrix<double> &distMat, RDKit::double_source_type &rng) { // make sure the sizes match up unsigned int npt = mmat.numRows(); CHECK_INVARIANT(npt == distMat.numRows(), "Size mismatch"); double largestVal = -1.0; double *ddata = distMat.getData(); for (unsigned int i = 1; i < npt; i++) { unsigned int id = i * (i + 1) / 2; for (unsigned int j = 0; j < i; j++) { double ub = mmat.getUpperBound(i, j); double lb = mmat.getLowerBound(i, j); CHECK_INVARIANT(ub >= lb, ""); double rval = rng(); // std::cerr<<i<<"-"<<j<<": "<<rval<<std::endl; double d = lb + (rval) * (ub - lb); ddata[id + j] = d; if (d > largestVal) { largestVal = d; } } } return largestVal; }
double pickRandomDistMat(const BoundsMatrix &mmat, RDNumeric::SymmMatrix<double> &distMat, int seed) { // make sure the sizes match up unsigned int npt = mmat.numRows(); CHECK_INVARIANT(npt == distMat.numRows(), "Size mismatch"); RDKit::rng_type &generator = RDKit::getRandomGenerator(); if (seed > 0) { generator.seed(seed); } double largestVal=-1.0; double *ddata = distMat.getData(); for (unsigned int i = 1; i < npt; i++) { unsigned int id = i*(i+1)/2; for (unsigned int j = 0; j < i; j++) { double ub = mmat.getUpperBound(i,j); double lb = mmat.getLowerBound(i,j); CHECK_INVARIANT(ub >= lb, ""); double rval = RDKit::getRandomVal(); double d = lb + (rval)*(ub - lb); ddata[id+j] = d; if(d>largestVal){ largestVal=d; } } } return largestVal; }
bool computeInitialCoords(const RDNumeric::SymmMatrix<double> &distMat, RDGeom::PointPtrVect &positions, RDKit::double_source_type &rng, bool randNegEig, unsigned int numZeroFail) { unsigned int N = distMat.numRows(); unsigned int nPt = positions.size(); CHECK_INVARIANT(nPt == N, "Size mismatch"); unsigned int dim = positions.front()->dimension(); const double *data = distMat.getData(); RDNumeric::SymmMatrix<double> sqMat(N), T(N, 0.0); RDNumeric::DoubleMatrix eigVecs(dim, N); RDNumeric::DoubleVector eigVals(dim); double *sqDat = sqMat.getData(); unsigned int dSize = distMat.getDataSize(); double sumSqD2 = 0.0; for (unsigned int i = 0; i < dSize; i++) { sqDat[i] = data[i] * data[i]; sumSqD2 += sqDat[i]; } sumSqD2 /= (N * N); RDNumeric::DoubleVector sqD0i(N, 0.0); double *sqD0iData = sqD0i.getData(); for (unsigned int i = 0; i < N; i++) { for (unsigned int j = 0; j < N; j++) { sqD0iData[i] += sqMat.getVal(i, j); } sqD0iData[i] /= N; sqD0iData[i] -= sumSqD2; if ((sqD0iData[i] < EIGVAL_TOL) && (N > 3)) { return false; } } for (unsigned int i = 0; i < N; i++) { for (unsigned int j = 0; j <= i; j++) { double val = 0.5 * (sqD0iData[i] + sqD0iData[j] - sqMat.getVal(i, j)); T.setVal(i, j, val); } } unsigned int nEigs = (dim < N) ? dim : N; RDNumeric::EigenSolvers::powerEigenSolver(nEigs, T, eigVals, eigVecs, (int)(sumSqD2 * N)); double *eigData = eigVals.getData(); bool foundNeg = false; unsigned int zeroEigs = 0; for (unsigned int i = 0; i < dim; i++) { if (eigData[i] > EIGVAL_TOL) { eigData[i] = sqrt(eigData[i]); } else if (fabs(eigData[i]) < EIGVAL_TOL) { eigData[i] = 0.0; zeroEigs++; } else { foundNeg = true; } } if ((foundNeg) && (!randNegEig)) { return false; } if ((zeroEigs >= numZeroFail) && (N > 3)) { return false; } for (unsigned int i = 0; i < N; i++) { RDGeom::Point *pt = positions[i]; for (unsigned int j = 0; j < dim; ++j) { if (eigData[j] >= 0.0) { (*pt)[j] = eigData[j] * eigVecs.getVal(j, i); } else { // std::cerr<<"!!! "<<i<<"-"<<j<<": "<<eigData[j]<<std::endl; (*pt)[j] = 1.0 - 2.0 * rng(); } } } return true; }