Loading...
Searching...
No Matches
eonc::helpers::surrogate Namespace Reference

Functions

MatrixXd get_features (const std::vector< Matter > &matobjs)
MatrixXd get_features (const std::vector< std::shared_ptr< Matter > > &matobjs)
MatrixXd get_targets (std::vector< Matter > &matobjs, std::shared_ptr< Potential > true_pot)
MatrixXd get_targets (std::vector< std::shared_ptr< Matter > > &matobjs, std::shared_ptr< Potential > true_pot)
std::vector< Matter > getMidSlice (const std::vector< Matter > &matobjs)
Eigen::VectorXd make_target (Matter &m1, std::shared_ptr< Potential > true_pot)
std::pair< double, Eigen::VectorXd::Index > getMaxUncertainty (const std::vector< std::shared_ptr< Matter > > &matobjs)
std::pair< Eigen::VectorXd, Eigen::VectorXd > getNewDataPoint (const std::vector< std::shared_ptr< Matter > > &matobjs, std::shared_ptr< Potential > true_pot)
bool accuratePES (std::vector< std::shared_ptr< Matter > > &matobjs, std::shared_ptr< Potential > true_pot)

Function Documentation

◆ accuratePES()

bool eonc::helpers::surrogate::accuratePES ( std::vector< std::shared_ptr< Matter > > & matobjs,
std::shared_ptr< Potential > true_pot )

Definition at line 305 of file GPSurrogateJob.cpp.

306 {
307 if (matobjs.empty()) {
308 throw std::invalid_argument("accuratePES: empty path");
309 }
310 Eigen::VectorXd predEnergies{Eigen::VectorXd::Zero(matobjs.size())};
311 Eigen::VectorXd trueEnergies{Eigen::VectorXd::Zero(matobjs.size())};
312 for (auto idx{0}; idx < predEnergies.size(); idx++) {
313 auto incoming = matobjs[idx]->getPotential();
314 predEnergies[idx] = matobjs[idx]->getPotentialEnergy();
315 matobjs[idx]->setPotential(true_pot);
316 trueEnergies[idx] = matobjs[idx]->getPotentialEnergy();
317 matobjs[idx]->setPotential(incoming);
318 }
319 Eigen::VectorXd difference = predEnergies - trueEnergies;
320 const auto maxAbs = difference.array().abs().maxCoeff();
321 std::ostringstream oss;
322 oss << "predicted\n"
323 << predEnergies << "\ntrue\n"
324 << trueEnergies << "\ndifference\n"
325 << difference << "\n maxAbs: " << maxAbs;
326 EONC_LOG_TRACE("{}", oss.str());
327 return maxAbs < 0.05;
328}
#define EONC_LOG_TRACE(...)
Convenience macro for one-shot logging without storing a logger.
Definition EonLogger.h:237

◆ get_features() [1/2]

MatrixXd eonc::helpers::surrogate::get_features ( const std::vector< Matter > & matobjs)

Definition at line 202 of file GPSurrogateJob.cpp.

202 {
203 // Calculate dimensions
204 MatrixXd features(matobjs.size(), matobjs.front().numberOfFreeAtoms() * 3);
205 EONC_LOG_TRACE("rows: {}, cols:{}", matobjs.size(),
206 matobjs.front().numberOfFreeAtoms() * 3);
207 for (long idx{0}; idx < features.rows(); idx++) {
208 features.row(idx) = matobjs[idx].getPositionsFreeV();
209 }
210 std::ostringstream oss;
211 oss << features;
212 EONC_LOG_TRACE("Features\n:{}", oss.str());
213 return features;
214}
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, eOnStorageOrder > MatrixXd
Definition Eigen.h:33

◆ get_features() [2/2]

MatrixXd eonc::helpers::surrogate::get_features ( const std::vector< std::shared_ptr< Matter > > & matobjs)

Definition at line 215 of file GPSurrogateJob.cpp.

215 {
216 // Calculate dimensions
217 MatrixXd features(matobjs.size(), matobjs.front()->numberOfFreeAtoms() * 3);
218 EONC_LOG_TRACE("rows: {}, cols:{}\n", matobjs.size(),
219 matobjs.front()->numberOfFreeAtoms() * 3);
220 for (long idx{0}; idx < features.rows(); idx++) {
221 features.row(idx) = matobjs[idx]->getPositionsFreeV();
222 }
223 std::ostringstream oss;
224 oss << features;
225 EONC_LOG_TRACE("Features\n:{}", oss.str());
226 return features;
227}

◆ get_targets() [1/2]

MatrixXd eonc::helpers::surrogate::get_targets ( std::vector< Matter > & matobjs,
std::shared_ptr< Potential > true_pot )

Definition at line 228 of file GPSurrogateJob.cpp.

229 {
230 // Always with derivatives for now
231 // Energy + Derivatives for each row
232 const auto nrows = matobjs.size();
233 const auto ncols = (matobjs.front().numberOfFreeAtoms() * 3) + 1;
234 MatrixXd targets(nrows, ncols);
235 for (long idx{0}; idx < targets.rows(); idx++) {
236 matobjs[idx].setPotential(true_pot);
237 targets.row(idx)[0] = matobjs[idx].getPotentialEnergy();
238 targets.block(idx, 1, 1, ncols - 1) =
239 matobjs[idx].getForcesFreeV().array() * -1;
240 }
241 std::ostringstream oss;
242 oss << targets;
243 EONC_LOG_TRACE("Targets\n:{}", oss.str());
244 return targets;
245}

◆ get_targets() [2/2]

MatrixXd eonc::helpers::surrogate::get_targets ( std::vector< std::shared_ptr< Matter > > & matobjs,
std::shared_ptr< Potential > true_pot )

Definition at line 246 of file GPSurrogateJob.cpp.

247 {
248 const auto nrows = matobjs.size();
249 const auto ncols = (matobjs.front()->numberOfFreeAtoms() * 3) + 1;
250 MatrixXd targets(nrows, ncols);
251 for (long idx{0}; idx < targets.rows(); idx++) {
252 matobjs[idx]->setPotential(true_pot);
253 targets.row(idx)[0] = matobjs[idx]->getPotentialEnergy();
254 targets.block(idx, 1, 1, ncols - 1) =
255 matobjs[idx]->getForcesFreeV().array() * -1;
256 }
257 std::ostringstream oss;
258 oss << targets;
259 EONC_LOG_TRACE("Targets\n:{}", oss.str());
260 return targets;
261}

◆ getMaxUncertainty()

std::pair< double, Eigen::VectorXd::Index > eonc::helpers::surrogate::getMaxUncertainty ( const std::vector< std::shared_ptr< Matter > > & matobjs)

Definition at line 283 of file GPSurrogateJob.cpp.

283 {
284 if (matobjs.size() < 3) {
285 throw std::invalid_argument(
286 "getMaxUncertainty: need at least three images");
287 }
288 Eigen::VectorXd pathUncertainty{Eigen::VectorXd::Zero(matobjs.size() - 2)};
289 for (auto idx{0}; idx < pathUncertainty.size(); idx++) {
290 pathUncertainty[idx] = matobjs[idx + 1]->getEnergyVariance();
291 }
292 Eigen::VectorXd::Index maxIndex;
293 double maxUnc{pathUncertainty.maxCoeff()};
294 pathUncertainty.maxCoeff(&maxIndex);
295 return std::make_pair(maxUnc, maxIndex);
296}

◆ getMidSlice()

std::vector< Matter > eonc::helpers::surrogate::getMidSlice ( const std::vector< Matter > & matobjs)

Definition at line 262 of file GPSurrogateJob.cpp.

262 {
263 // Initial GP slice: endpoints plus one interior sample. CatLearn
264 // training is order-sensitive (front, back, interior). The interior
265 // index is two-thirds along the movable images, not n/2.
266 if (matobjs.size() < 3) {
267 throw std::invalid_argument("getMidSlice: need at least three images");
268 }
269 const std::size_t n = matobjs.size();
270 const std::size_t twoThirds =
271 static_cast<std::size_t>(((n - 2) * 2.0 / 3.0) + 1.0);
272 return {matobjs.front(), matobjs.back(), matobjs[twoThirds]};
273}

◆ getNewDataPoint()

std::pair< Eigen::VectorXd, Eigen::VectorXd > eonc::helpers::surrogate::getNewDataPoint ( const std::vector< std::shared_ptr< Matter > > & matobjs,
std::shared_ptr< Potential > true_pot )

Definition at line 298 of file GPSurrogateJob.cpp.

299 {
300 auto [maxUnc, maxIndex] = getMaxUncertainty(matobjs);
301 Matter candidate{*matobjs[maxIndex + 1]};
302 return std::make_pair<Eigen::VectorXd, Eigen::VectorXd>(
303 candidate.getPositionsFreeV(), make_target(candidate, true_pot));
304}
VectorXd getPositionsFreeV() const
Definition Matter.cpp:345
std::pair< double, Eigen::VectorXd::Index > getMaxUncertainty(const std::vector< std::shared_ptr< Matter > > &matobjs)
Eigen::VectorXd make_target(Matter &m1, std::shared_ptr< Potential > true_pot)

◆ make_target()

Eigen::VectorXd eonc::helpers::surrogate::make_target ( Matter & m1,
std::shared_ptr< Potential > true_pot )

Definition at line 274 of file GPSurrogateJob.cpp.

274 {
275 const auto ncols = (m1.numberOfFreeAtoms() * 3) + 1;
276 Eigen::VectorXd target(ncols);
277 m1.setPotential(true_pot);
278 target(0) = m1.getPotentialEnergy();
279 target.segment(1, ncols - 1) = m1.getForcesFreeV() * -1;
280 return target;
281}
VectorXd getForcesFreeV() const
Definition Matter.cpp:442
void setPotential(std::shared_ptr< Potential > pot)
Definition Matter.cpp:754
double getPotentialEnergy() const
Definition Matter.cpp:554
long int numberOfFreeAtoms() const
Definition Matter.cpp:583