mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
* Add RealValueVect.
* Add UniformRealValueGrid3D
* Add Molecular Interaction Fields (MIFs)
* line endings
* cherry-pick f1bc94a4c8
* format
* Adapt tests for python3.
* Adapt RealValueVector pickling for python3.
* Speed-up of MIF calculations.
* Bugfix in MIFDescriptors.cpp.
* all tests pass
* clean up some memory leaks
* update copyrights
* rename
* rename the library
* complete the rename
* lost file
* another forgotten file
* cleanup
* clang-tidy
* clang-tidy
* windows DLL builds work
* python wrapper and tests cleanup
* convert to catch2 testing
* switch RealValueVect to use std::vector
* remove obsolete friend
* - Replace explicit loops with stdlib implicit equivalents
- Replace explicit types with auto where possible
- Avoid unnecessary copy operations where possible
- Replace raw pointers with exception-safe unique_ptr
- Replace C-style #define with constexpr
- Replace C-style casts with C++ casts
- Replace C-style arrays with std::vector
- Avoid code duplication with templated operators
- Replace VdWaals class taking multiple atom type definitions and force-field name as string parameter with force-field-specific classes deriving from an abstract VdWaals class
- Replace x,y,z doubles with Point3D class where possible
- Removed unused (and untested) DistanceToClosestAtom class
- Renamed some variables and functions for better clarity
- Converted tabs to spaces
- Made the mol parameter in cube read/write functions optional for convenience
- Made the Python wrappers more pythonic (e.g., avoid C++-style passing objects as parameters which are modified in place)
- Implemented alternative Python class constructors using boost::python::make_constructor rather than with external non-class functions
- The Python wrappers taking a sequence of Point3D now take a sequence of sequences, such that the output of Conformer.GetPositions() can be passed
- Made the Python wrapper sequence parsing more robust
- Removed duplicated code from Python wrappers
* - avoid an unnecessary copy
* progress
* works
* more cleanup
* all tests pass
* changes in response to review
---------
Co-authored-by: dfhahn <dfhahn@users.noreply.github.com>
Co-authored-by: ptosco <paolo.tosco@novartis.com>
165 lines
4.7 KiB
C++
165 lines
4.7 KiB
C++
//
|
|
// Copyright (c) 2014-2024, Novartis Institutes for BioMedical Research and
|
|
// other RDKit contributors
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
// This file is part of the RDKit.
|
|
// The contents are covered by the terms of the BSD license
|
|
// which is included in the file license.txt, found at the root
|
|
// of the RDKit source tree.
|
|
//
|
|
#include "RealValueVect.h"
|
|
#include <RDGeneral/Invariant.h>
|
|
#include <RDGeneral/StreamOps.h>
|
|
#include "DatastructsException.h"
|
|
|
|
constexpr double VAL_TOL = 0.01;
|
|
|
|
namespace RDKit {
|
|
const int ci_REALVALUEVECTPICKLE_VERSION = 0x1;
|
|
|
|
double RealValueVect::getVal(unsigned int i) const {
|
|
if (i >= d_length) {
|
|
throw IndexErrorException(i);
|
|
}
|
|
return d_data[i];
|
|
}
|
|
|
|
void RealValueVect::setVal(unsigned int i, double val) {
|
|
if (i >= d_length) {
|
|
throw IndexErrorException(i);
|
|
}
|
|
d_data[i] = val;
|
|
}
|
|
|
|
double RealValueVect::getTotalVal() const {
|
|
return std::accumulate(d_data.begin(), d_data.end(), 0.0,
|
|
std::plus<double>());
|
|
}
|
|
|
|
bool RealValueVect::compareVectors(const RealValueVect &other) const {
|
|
if (getLength() != other.getLength()) {
|
|
throw ValueErrorException("Comparing vectors of different lengths");
|
|
}
|
|
return std::equal(this->d_data.begin(), this->d_data.end(),
|
|
other.d_data.begin(), [](auto v1, auto v2) {
|
|
return fabs((v1 - v2) / (v1 != 0 ? v1 : 1)) <= VAL_TOL;
|
|
});
|
|
}
|
|
|
|
double computeL1Norm(const RealValueVect &v1, const RealValueVect &v2) {
|
|
if (v1.getLength() != v2.getLength()) {
|
|
throw ValueErrorException("Comparing vectors of different lengths");
|
|
}
|
|
double res = 0.0;
|
|
for (auto i = 0u; i < v1.getLength(); ++i) {
|
|
res += fabs(v1.getData()[i] - v2.getData()[i]);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
std::string RealValueVect::toString() const {
|
|
std::stringstream ss(std::ios_base::binary | std::ios_base::out |
|
|
std::ios_base::in);
|
|
|
|
std::int32_t tVers = ci_REALVALUEVECTPICKLE_VERSION * -1;
|
|
streamWrite(ss, tVers);
|
|
std::uint32_t tInt = d_length;
|
|
streamWrite(ss, tInt);
|
|
|
|
#if defined(BOOST_BIG_ENDIAN)
|
|
std::vector<double> td(d_length);
|
|
std::transform(d_data.begin(), d_data.end(), td.begin(), [](const auto v) {
|
|
return EndianSwapBytes<HOST_ENDIAN_ORDER, LITTLE_ENDIAN_ORDER>(v);
|
|
});
|
|
ss.write(reinterpret_cast<const char *>(td.data()),
|
|
d_length * sizeof(double));
|
|
const auto *data = td.data();
|
|
#else
|
|
const auto *data = d_data.data();
|
|
#endif
|
|
ss.write(reinterpret_cast<const char *>(data), d_length * sizeof(double));
|
|
return ss.str();
|
|
};
|
|
|
|
void RealValueVect::initFromText(const char *pkl, const unsigned int len) {
|
|
std::stringstream ss(std::ios_base::binary | std::ios_base::in |
|
|
std::ios_base::out);
|
|
ss.write(pkl, len);
|
|
std::int32_t tVers;
|
|
streamRead(ss, tVers);
|
|
tVers *= -1;
|
|
if (tVers != 0x1) {
|
|
throw ValueErrorException("bad version in RealValueVect pickle");
|
|
}
|
|
std::uint32_t tInt;
|
|
streamRead(ss, tInt);
|
|
d_length = tInt;
|
|
d_data.resize(d_length);
|
|
auto *data = d_data.data();
|
|
ss.read(reinterpret_cast<char *>(data), d_length * sizeof(double));
|
|
|
|
#if defined(BOOST_BIG_ENDIAN)
|
|
std::transform(d_data.begin(), d_data.end(), d_data.begin(), [](auto &v) {
|
|
return EndianSwapBytes<LITTLE_ENDIAN_ORDER, HOST_ENDIAN_ORDER>(v);
|
|
});
|
|
#endif
|
|
};
|
|
|
|
template <typename O>
|
|
RealValueVect &RealValueVect::applyBinaryOp(const RealValueVect &other, O op) {
|
|
PRECONDITION(other.d_length == d_length, "length mismatch");
|
|
for (unsigned int i = 0; i < d_length; ++i) {
|
|
double v1 = getVal(i);
|
|
double v2 = other.getVal(i);
|
|
setVal(i, op(v1, v2));
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
RealValueVect &RealValueVect::operator&=(const RealValueVect &other) {
|
|
static const double &(*minOp)(const double &, const double &) =
|
|
std::min<double>;
|
|
return applyBinaryOp(other, minOp);
|
|
}
|
|
|
|
RealValueVect &RealValueVect::operator|=(const RealValueVect &other) {
|
|
static const double &(*maxOp)(const double &, const double &) =
|
|
std::max<double>;
|
|
return applyBinaryOp(other, maxOp);
|
|
}
|
|
|
|
RealValueVect &RealValueVect::operator+=(const RealValueVect &other) {
|
|
return applyBinaryOp(other, std::plus<double>());
|
|
}
|
|
|
|
RealValueVect &RealValueVect::operator-=(const RealValueVect &other) {
|
|
return applyBinaryOp(other, std::minus<double>());
|
|
}
|
|
|
|
RealValueVect operator+(const RealValueVect &p1, const RealValueVect &p2) {
|
|
RealValueVect res(p1);
|
|
res += p2;
|
|
return res;
|
|
}
|
|
|
|
RealValueVect operator-(const RealValueVect &p1, const RealValueVect &p2) {
|
|
RealValueVect res(p1);
|
|
res -= p2;
|
|
return res;
|
|
}
|
|
|
|
RealValueVect operator|(const RealValueVect &p1, const RealValueVect &p2) {
|
|
RealValueVect res(p1);
|
|
res |= p2;
|
|
return res;
|
|
};
|
|
|
|
RealValueVect operator&(const RealValueVect &p1, const RealValueVect &p2) {
|
|
RealValueVect res(p1);
|
|
res &= p2;
|
|
return res;
|
|
};
|
|
|
|
} // end of namespace RDKit
|