Chemical Data Processing Library C++ API - Version 1.4.0
DGCoordinatesGenerator.hpp
Go to the documentation of this file.
1 /*
2  * DGCoordinatesGenerator.hpp
3  *
4  * This file is part of the Chemical Data Processing Toolkit
5  *
6  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 #ifndef CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
30 #define CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
31 
32 #include <cstddef>
33 #include <vector>
34 #include <algorithm>
35 #include <cmath>
36 
37 #include <boost/random/mersenne_twister.hpp>
38 #include <boost/random/uniform_real.hpp>
39 #include <boost/random/uniform_int.hpp>
40 
41 #include "CDPL/Base/Exceptions.hpp"
42 
43 
44 namespace CDPL
45 {
46 
47  namespace Util
48  {
49 
57  template <std::size_t Dim, typename T, typename Derived>
59  {
60 
61  public:
62  class DistanceConstraint;
63 
64  private:
65  typedef std::vector<DistanceConstraint> DistanceConstraintList;
66 
67  public:
71  typedef typename DistanceConstraintList::iterator DistanceConstraintIterator;
72 
76  typedef typename DistanceConstraintList::const_iterator ConstDistanceConstraintIterator;
77 
81  typedef T ValueType;
82 
86  static constexpr std::size_t COORDS_DIM = Dim;
87 
91  static constexpr std::size_t DEF_NUM_CYCLES = 50;
92 
96  static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR = 1.0;
97 
101  static constexpr ValueType DEF_START_LEARNING_RATE = 1;
102 
106  static constexpr ValueType DEF_LEARNING_RATE_DECREMENT = 0.95 / 50;
107 
112  {
113 
114  public:
123  DistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
124 
129  std::size_t getPoint1Index() const;
130 
135  std::size_t getPoint2Index() const;
136 
141  const ValueType& getLowerBound() const;
142 
147  const ValueType& getUpperBound() const;
148 
154  bool operator<(const DistanceConstraint& constr) const;
155 
156  private:
157  std::size_t point1Idx;
158  std::size_t point2Idx;
159  ValueType lowerBound;
160  ValueType upperBound;
161  };
162 
167 
175  void addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
176 
181  std::size_t getNumDistanceConstraints() const;
182 
189  const DistanceConstraint& getDistanceConstraint(std::size_t idx) const;
190 
198 
204  void removeDistanceConstraint(std::size_t idx);
205 
212 
218 
224 
230 
236 
241  void setNumCycles(std::size_t num_cycles);
242 
247  void setCycleStepCountFactor(double fact);
248 
253  void setStartLearningRate(const ValueType& rate);
254 
260 
265  std::size_t getNumCycles() const;
266 
271  double getCycleStepCountFactor() const;
272 
278 
284 
289  void setRandomSeed(unsigned int seed);
290 
297  template <typename CoordsArray>
298  void generate(std::size_t num_points, CoordsArray& coords);
299 
306  template <typename CoordsArray>
307  ValueType getDistanceError(const CoordsArray& coords) const;
308 
313 
314  protected:
316 
318 
320 
322 
323  private:
324  std::size_t getNumVolumeConstraints() const;
325 
326  template <typename CoordsArray>
327  void embedCoords(std::size_t num_points, CoordsArray& coords);
328 
329  template <typename CoordsArray>
330  void adjCoordsForDistanceConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
331 
332  template <typename Vec>
333  void adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, const ValueType& lambda) const;
334 
335  template <typename CoordsArray>
336  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
337 
338  template <typename Vec>
339  static ValueType calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
340 
341  typedef boost::random::mt11213b RandNumEngine;
342 
343  std::size_t numCycles;
344  double cycleStepCountFactor;
345  ValueType startLearningRate;
346  ValueType learningRateDecr;
347  DistanceConstraintList distConstraints;
348  RandNumEngine randomEngine;
349  };
350 
351  template <std::size_t Dim, typename T, typename Derived>
353 
354  template <std::size_t Dim, typename T, typename Derived>
356 
357  template <std::size_t Dim, typename T, typename Derived>
359 
360  template <std::size_t Dim, typename T, typename Derived>
363 
364  template <std::size_t Dim, typename T, typename Derived>
367 
368 
375  template <std::size_t Dim, typename T>
376  class DGCoordinatesGenerator : public DGCoordinatesGeneratorBase<Dim, T, DGCoordinatesGenerator<Dim, T> >
377  {};
378 
379 
385  template <typename T>
386  class DGCoordinatesGenerator<3, T> : public DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >
387  {
388 
390  friend class DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >;
391 
392  public:
393  class VolumeConstraint;
394 
395  private:
396  typedef std::vector<VolumeConstraint> VolumeConstraintList;
397 
398  public:
402  typedef typename BaseType::ValueType ValueType;
403 
407  typedef typename VolumeConstraintList::iterator VolumeConstraintIterator;
408 
412  typedef typename VolumeConstraintList::const_iterator ConstVolumeConstraintIterator;
413 
417  class VolumeConstraint
418  {
419 
420  public:
430  VolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
431  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
432 
437  std::size_t getPoint1Index() const;
438 
443  std::size_t getPoint2Index() const;
444 
449  std::size_t getPoint3Index() const;
450 
455  std::size_t getPoint4Index() const;
456 
461  const ValueType& getLowerBound() const;
462 
467  const ValueType& getUpperBound() const;
468 
469  private:
470  std::size_t point1Idx;
471  std::size_t point2Idx;
472  std::size_t point3Idx;
473  std::size_t point4Idx;
474  ValueType lowerBound;
475  ValueType upperBound;
476  };
477 
482 
492  void addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
493  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
494 
499  std::size_t getNumVolumeConstraints() const;
500 
507  const VolumeConstraint& getVolumeConstraint(std::size_t idx) const;
508 
515  VolumeConstraint& getVolumeConstraint(std::size_t idx);
516 
522  void removeVolumeConstraint(std::size_t idx);
523 
530 
536 
542 
548 
554 
561  template <typename CoordsArray>
562  ValueType getVolumeError(const CoordsArray& coords) const;
563 
564  private:
565  template <typename CoordsArray>
566  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
567 
568  template <typename Vec>
569  void adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
570  Vec& pt4_pos, const ValueType& lambda) const;
571 
572  template <typename Vec>
573  static void calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
574 
575  VolumeConstraintList volConstraints;
576  };
577 
582  } // namespace Util
583 } // namespace CDPL
584 
585 
586 // \cond DOC_IMPL_DETAILS
587 // DGCoordinatesGeneratorBase<Dim, T>::DistanceConstraint implementation
588 
589 template <std::size_t Dim, typename T, typename Derived>
591  const ValueType& lb, const ValueType& ub):
592  point1Idx(pt1_idx),
593  point2Idx(pt2_idx), lowerBound(lb), upperBound(ub)
594 {}
595 
596 template <std::size_t Dim, typename T, typename Derived>
598 {
599  return point1Idx;
600 }
601 
602 template <std::size_t Dim, typename T, typename Derived>
604 {
605  return point2Idx;
606 }
607 
608 template <std::size_t Dim, typename T, typename Derived>
610 {
611  return lowerBound;
612 }
613 
614 template <std::size_t Dim, typename T, typename Derived>
616 {
617  return upperBound;
618 }
619 
620 template <std::size_t Dim, typename T, typename Derived>
622 {
623  if (point1Idx < constr.point1Idx)
624  return true;
625 
626  if (point1Idx == constr.point1Idx)
627  return (point2Idx < constr.point2Idx);
628 
629  return false;
630 }
631 
632 
633 // DGCoordinatesGeneratorBase<Dim, T, Derived> implementation
634 
635 template <std::size_t Dim, typename T, typename Derived>
637  numCycles(DEF_NUM_CYCLES), cycleStepCountFactor(DEF_CYCLE_STEP_COUNT_FACTOR), startLearningRate(DEF_START_LEARNING_RATE),
638  learningRateDecr(DEF_LEARNING_RATE_DECREMENT), randomEngine(170375)
639 {}
640 
641 template <std::size_t Dim, typename T, typename Derived>
643  numCycles(gen.numCycles), cycleStepCountFactor(gen.cycleStepCountFactor),
644  startLearningRate(gen.startLearningRate), learningRateDecr(gen.learningRateDecr),
645  distConstraints(gen.distConstraints),
646  randomEngine(gen.randomEngine)
647 {}
648 
649 template <std::size_t Dim, typename T, typename Derived>
651 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::operator=(const DGCoordinatesGeneratorBase& gen)
652 {
653  if (&gen == this)
654  return *this;
655 
656  numCycles = gen.numCycles;
657  cycleStepCountFactor = gen.cycleStepCountFactor;
658  startLearningRate = gen.startLearningRate;
659  learningRateDecr = gen.learningRateDecr;
660  distConstraints = gen.distConstraints;
661  randomEngine = gen.randomEngine;
662 
663  return *this;
664 }
665 
666 template <std::size_t Dim, typename T, typename Derived>
668 {
669  distConstraints.clear();
670 }
671 
672 template <std::size_t Dim, typename T, typename Derived>
673 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx,
674  const ValueType& lb, const ValueType& ub)
675 {
676  distConstraints.push_back(DistanceConstraint(pt1_idx, pt2_idx, lb, ub));
677 }
678 
679 template <std::size_t Dim, typename T, typename Derived>
681 {
682  return distConstraints.size();
683 }
684 
685 template <std::size_t Dim, typename T, typename Derived>
688 {
689  if (idx >= distConstraints.size())
690  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
691 
692  return distConstraints[idx];
693 }
694 
695 template <std::size_t Dim, typename T, typename Derived>
698 {
699  if (idx >= distConstraints.size())
700  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
701 
702  return distConstraints[idx];
703 }
704 
705 template <std::size_t Dim, typename T, typename Derived>
707 {
708  if (idx >= distConstraints.size())
709  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
710 
711  distConstraints.erase(distConstraints.begin() + idx);
712 }
713 
714 template <std::size_t Dim, typename T, typename Derived>
716 {
717  if ((it - distConstraints.begin()) >= distConstraints.size())
718  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint iterator out of bounds");
719 
720  distConstraints.erase(it);
721 }
722 
723 template <std::size_t Dim, typename T, typename Derived>
726 {
727  return distConstraints.begin();
728 }
729 
730 template <std::size_t Dim, typename T, typename Derived>
733 {
734  return distConstraints.end();
735 }
736 
737 template <std::size_t Dim, typename T, typename Derived>
740 {
741  return distConstraints.begin();
742 }
743 
744 template <std::size_t Dim, typename T, typename Derived>
747 {
748  return distConstraints.end();
749 }
750 
751 template <std::size_t Dim, typename T, typename Derived>
753 {
754  numCycles = num_cycles;
755 }
756 
757 template <std::size_t Dim, typename T, typename Derived>
759 {
760  cycleStepCountFactor = fact;
761 }
762 
763 template <std::size_t Dim, typename T, typename Derived>
765 {
766  startLearningRate = rate;
767 }
768 
769 template <std::size_t Dim, typename T, typename Derived>
771 {
772  learningRateDecr = decr;
773 }
774 
775 template <std::size_t Dim, typename T, typename Derived>
777 {
778  return numCycles;
779 }
780 
781 template <std::size_t Dim, typename T, typename Derived>
783 {
784  return cycleStepCountFactor;
785 }
786 
787 template <std::size_t Dim, typename T, typename Derived>
790 {
791  return startLearningRate;
792 }
793 
794 template <std::size_t Dim, typename T, typename Derived>
797 {
798  return learningRateDecr;
799 }
800 
801 template <std::size_t Dim, typename T, typename Derived>
803 {
804  randomEngine.seed(seed);
805 }
806 
807 template <std::size_t Dim, typename T, typename Derived>
808 template <typename CoordsArray>
811 {
812  ValueType error = ValueType();
813  ValueType pos_diff[Dim];
814 
815  for (typename DistanceConstraintList::const_iterator it = distConstraints.begin(), end = distConstraints.end(); it != end; ++it) {
816  const DistanceConstraint& constr = *it;
817 
818  ValueType dist_2 = calcDiffVectorAndSquaredDist(coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], pos_diff);
819  ValueType dist = std::sqrt(dist_2);
820  ValueType lb = constr.getLowerBound();
821  ValueType ub = constr.getUpperBound();
822 
823  if (dist >= lb && dist <= ub)
824  continue;
825 
826  if (dist < lb) {
827  ValueType tmp = (dist_2 - lb * lb) / (0.000001 + lb * lb);
828 
829  error += tmp * tmp;
830 
831  } else {
832  ValueType tmp = (dist_2 - ub * ub) / (0.000001 + ub * ub);
833 
834  error += tmp * tmp;
835  }
836  }
837 
838  return error;
839 }
840 
841 template <std::size_t Dim, typename T, typename Derived>
843 {
844  return 0;
845 }
846 
847 template <std::size_t Dim, typename T, typename Derived>
849 {
850  std::sort(distConstraints.begin(), distConstraints.end());
851 }
852 
853 template <std::size_t Dim, typename T, typename Derived>
854 template <typename CoordsArray>
855 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::generate(std::size_t num_points, CoordsArray& coords)
856 {
857  embedCoords(num_points, coords);
858 }
859 
860 template <std::size_t Dim, typename T, typename Derived>
861 template <typename CoordsArray>
862 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::embedCoords(std::size_t num_points, CoordsArray& coords)
863 {
864  std::size_t num_dist_constrs = distConstraints.size();
865  std::size_t num_vol_constrs = static_cast<Derived&>(*this).getNumVolumeConstraints();
866 
867  if ((num_dist_constrs + num_vol_constrs) == 0)
868  return;
869 
870  std::size_t num_steps = std::size_t((num_dist_constrs + num_vol_constrs) * cycleStepCountFactor);
871  ValueType lambda = startLearningRate;
872 
873  if (num_dist_constrs > 0 && num_vol_constrs > 0) {
874  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs + num_vol_constrs - 1);
875 
876  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr) {
877  for (std::size_t j = 0; j < num_steps; j++) {
878  std::size_t constr_idx = constr_sd(randomEngine);
879 
880  if (constr_idx < num_dist_constrs)
881  adjCoordsForDistanceConstraint(coords, lambda, constr_idx);
882  else
883  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_idx - num_dist_constrs);
884  }
885  }
886 
887  return;
888  }
889 
890  if (num_dist_constrs > 0) {
891  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs - 1);
892 
893  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
894  for (std::size_t j = 0; j < num_steps; j++)
895  adjCoordsForDistanceConstraint(coords, lambda, constr_sd(randomEngine));
896 
897  return;
898  }
899 
900  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_vol_constrs - 1);
901 
902  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
903  for (std::size_t j = 0; j < num_steps; j++)
904  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_sd(randomEngine));
905 }
906 
907 template <std::size_t Dim, typename T, typename Derived>
908 template <typename CoordsArray>
910  std::size_t constr_idx) const
911 {
912  const DistanceConstraint& constr = distConstraints[constr_idx];
913 
914  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], lambda);
915 }
916 
917 template <std::size_t Dim, typename T, typename Derived>
918 template <typename Vec>
919 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos,
920  Vec& pt2_pos, const ValueType& lambda) const
921 {
922  ValueType pos_diff[Dim];
923  ValueType dist = std::sqrt(calcDiffVectorAndSquaredDist(pt1_pos, pt2_pos, pos_diff));
924 
925  ValueType ub = constr.getUpperBound();
926  ValueType lb = constr.getLowerBound();
927 
928  if (dist >= lb && dist <= ub)
929  return;
930 
931  ValueType bound = (dist > ub ? ub : lb);
932  ValueType factor = lambda / 2 * (bound - dist) / (0.000001 + dist);
933 
934  for (std::size_t i = 0; i < Dim; i++) {
935  ValueType pos_delta = pos_diff[i] * factor;
936 
937  pt1_pos[i] -= pos_delta;
938  pt2_pos[i] += pos_delta;
939  }
940 }
941 
942 template <std::size_t Dim, typename T, typename Derived>
943 template <typename CoordsArray>
944 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda,
945  std::size_t constr_idx) const
946 {}
947 
948 template <std::size_t Dim, typename T, typename Derived>
949 template <typename Vec>
951 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
952 {
953  ValueType dist_2 = ValueType();
954 
955  for (std::size_t i = 0; i < Dim; i++) {
956  diff[i] = pt2_pos[i] - pt1_pos[i];
957  dist_2 += diff[i] * diff[i];
958  }
959 
960  return dist_2;
961 }
962 
963 
964 // DGCoordinatesGenerator<3, T>::VolumeConstraint implementation
965 
966 template <typename T>
968  std::size_t pt3_idx, std::size_t pt4_idx,
969  const ValueType& lb, const ValueType& ub):
970  point1Idx(pt1_idx),
971  point2Idx(pt2_idx), point3Idx(pt3_idx), point4Idx(pt4_idx), lowerBound(lb), upperBound(ub)
972 {}
973 
974 template <typename T>
976 {
977  return point1Idx;
978 }
979 
980 template <typename T>
982 {
983  return point2Idx;
984 }
985 
986 template <typename T>
988 {
989  return point3Idx;
990 }
991 
992 template <typename T>
994 {
995  return point4Idx;
996 }
997 
998 template <typename T>
1001 {
1002  return lowerBound;
1003 }
1004 
1005 template <typename T>
1008 {
1009  return upperBound;
1010 }
1011 
1012 
1013 // DGCoordinatesGenerator<3, T> implementation
1014 
1015 template <typename T>
1017 {
1018  volConstraints.clear();
1019 }
1020 
1021 template <typename T>
1022 void CDPL::Util::DGCoordinatesGenerator<3, T>::addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
1023  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub)
1024 {
1025  volConstraints.push_back(VolumeConstraint(pt1_idx, pt2_idx, pt3_idx, pt4_idx, lb, ub));
1026 }
1027 
1028 template <typename T>
1030 {
1031  return volConstraints.size();
1032 }
1033 
1034 template <typename T>
1037 {
1038  if (idx >= volConstraints.size())
1039  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
1040 
1041  return volConstraints[idx];
1042 }
1043 
1044 template <typename T>
1046 {
1047  if (idx >= volConstraints.size())
1048  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
1049 
1050  volConstraints.erase(volConstraints.begin() + idx);
1051 }
1052 
1053 template <typename T>
1054 void CDPL::Util::DGCoordinatesGenerator<3, T>::removeVolumeConstraint(const VolumeConstraintIterator& it)
1055 {
1056  if ((it - volConstraints.begin()) >= volConstraints.size())
1057  throw Base::IndexError("DGCoordinatesGenerator: constraint iterator out of bounds");
1058 
1059  volConstraints.erase(it);
1060 }
1061 
1062 template <typename T>
1065 {
1066  return volConstraints.begin();
1067 }
1068 
1069 template <typename T>
1072 {
1073  return volConstraints.end();
1074 }
1075 
1076 template <typename T>
1079 {
1080  return volConstraints.begin();
1081 }
1082 
1083 template <typename T>
1086 {
1087  return volConstraints.end();
1088 }
1089 
1090 template <typename T>
1091 template <typename CoordsArray>
1093 CDPL::Util::DGCoordinatesGenerator<3, T>::getVolumeError(const CoordsArray& coords) const
1094 {
1095  ValueType error = ValueType();
1096  ValueType v_41[3];
1097  ValueType v_42[3];
1098  ValueType v_43[3];
1099 
1100  for (typename VolumeConstraintList::const_iterator it = volConstraints.begin(), end = volConstraints.end(); it != end; ++it) {
1101  const VolumeConstraint& constr = *it;
1102 
1103  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint1Index()], v_41);
1104  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint2Index()], v_42);
1105  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint3Index()], v_43);
1106 
1107  ValueType vol = (v_41[0] * (v_42[1] * v_43[2] - v_42[2] * v_43[1]) - v_41[1] * (v_42[0] * v_43[2] - v_42[2] * v_43[0]) + v_41[2] * (v_42[0] * v_43[1] - v_42[1] * v_43[0])) / 6;
1108 
1109  ValueType lb = constr.getLowerBound();
1110  ValueType ub = constr.getUpperBound();
1111 
1112  if (vol >= lb && vol <= ub)
1113  continue;
1114 
1115  if (vol < lb) {
1116  ValueType tmp = (vol - lb);
1117 
1118  error += tmp * tmp;
1119 
1120  } else {
1121  ValueType tmp = (vol - ub);
1122 
1123  error += tmp * tmp;
1124  }
1125  }
1126 
1127  return error;
1128 }
1129 
1130 template <typename T>
1131 template <typename CoordsArray>
1132 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const
1133 {
1134  const VolumeConstraint& constr = volConstraints[constr_idx];
1135 
1136  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()],
1137  coords[constr.getPoint3Index()], coords[constr.getPoint4Index()], lambda);
1138 }
1139 
1140 template <typename T>
1141 template <typename Vec>
1142 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
1143  Vec& pt4_pos, const ValueType& lambda) const
1144 {
1145  Vec* pt_pos[4] = {&pt1_pos, &pt2_pos, &pt3_pos, &pt4_pos};
1146  ValueType v_41[3];
1147  ValueType v_42[3];
1148  ValueType v_43[3];
1149 
1150  calcDiffVector(*pt_pos[3], *pt_pos[0], v_41);
1151  calcDiffVector(*pt_pos[3], *pt_pos[1], v_42);
1152  calcDiffVector(*pt_pos[3], *pt_pos[2], v_43);
1153 
1154  ValueType g[4][3];
1155 
1156  g[0][0] = (v_42[1] * v_43[2] - v_42[2] * v_43[1]) / 6;
1157  g[0][1] = -(v_42[0] * v_43[2] - v_42[2] * v_43[0]) / 6;
1158  g[0][2] = (v_42[0] * v_43[1] - v_42[1] * v_43[0]) / 6;
1159 
1160  ValueType vol = (v_41[0] * g[0][0] + v_41[1] * g[0][1] + v_41[2] * g[0][2]);
1161  ValueType ub = constr.getUpperBound();
1162  ValueType lb = constr.getLowerBound();
1163 
1164  if (vol >= lb && vol <= ub)
1165  return;
1166 
1167  g[1][0] = (v_41[2] * v_43[1] - v_41[1] * v_43[2]) / 6;
1168  g[1][1] = (v_41[0] * v_43[2] - v_41[2] * v_43[0]) / 6;
1169  g[1][2] = (v_41[1] * v_43[0] - v_41[0] * v_43[1]) / 6;
1170 
1171  g[2][0] = (v_41[1] * v_42[2] - v_41[2] * v_42[1]) / 6;
1172  g[2][1] = (v_41[2] * v_42[0] - v_41[0] * v_42[2]) / 6;
1173  g[2][2] = (v_41[0] * v_42[1] - v_41[1] * v_42[0]) / 6;
1174 
1175  g[3][0] = -g[0][0] - g[1][0] - g[2][0];
1176  g[3][1] = -g[0][1] - g[1][1] - g[2][1];
1177  g[3][2] = -g[0][2] - g[1][2] - g[2][2];
1178 
1179  ValueType g_len2_sum = ValueType();
1180 
1181  for (std::size_t i = 0; i < 4; i++)
1182  g_len2_sum += g[i][0] * g[i][0] + g[i][1] * g[i][1] + g[i][2] * g[i][2];
1183 
1184  ValueType bound = (vol < lb ? lb : ub);
1185  ValueType fact = lambda * (bound - vol) / g_len2_sum;
1186 
1187  for (std::size_t i = 0; i < 4; i++)
1188  for (std::size_t j = 0; j < 3; j++)
1189  (*pt_pos[i])[j] += fact * g[i][j];
1190 }
1191 
1192 template <typename T>
1193 template <typename Vec>
1194 void CDPL::Util::DGCoordinatesGenerator<3, T>::calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
1195 {
1196  for (std::size_t i = 0; i < 3; i++)
1197  diff[i] = pt2_pos[i] - pt1_pos[i];
1198 }
1199 
1200 // \endcond
1201 
1202 #endif // CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
Definition of exception classes.
A constraint that pins the distance between two points to the interval [lb, ub].
Definition: DGCoordinatesGenerator.hpp:112
bool operator<(const DistanceConstraint &constr) const
Lexicographic less-than comparison on (point1Idx, point2Idx).
std::size_t getPoint1Index() const
Returns the index of the first constrained point.
std::size_t getPoint2Index() const
Returns the index of the second constrained point.
DistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType &lb, const ValueType &ub)
Constructs a distance constraint for the points with indices pt1_idx and pt2_idx whose Euclidean dist...
const ValueType & getLowerBound() const
Returns the lower distance bound.
const ValueType & getUpperBound() const
Returns the upper distance bound.
Serves as foundation for subclasses that perform coordinates generation based on distance-geometry.
Definition: DGCoordinatesGenerator.hpp:59
~DGCoordinatesGeneratorBase()
Definition: DGCoordinatesGenerator.hpp:319
std::size_t getNumCycles() const
Returns the currently configured number of optimization cycles.
void setNumCycles(std::size_t num_cycles)
Sets the number of optimization cycles.
DGCoordinatesGeneratorBase & operator=(const DGCoordinatesGeneratorBase &gen)
const ValueType & getStartLearningRate() const
Returns the currently configured initial learning rate.
void setCycleStepCountFactor(double fact)
Sets the multiplier that determines the per-cycle step count (steps per cycle = factor * number of co...
void setStartLearningRate(const ValueType &rate)
Sets the initial learning rate used by the first optimization cycle.
DistanceConstraint & getDistanceConstraint(std::size_t idx)
Returns the distance constraint at index idx.
static constexpr std::size_t DEF_NUM_CYCLES
Default number of optimization cycles.
Definition: DGCoordinatesGenerator.hpp:91
static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR
Default per-cycle step-count multiplier (steps per cycle = factor * number of constraints).
Definition: DGCoordinatesGenerator.hpp:96
void addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType &lb, const ValueType &ub)
Appends a new distance constraint to the list of configured constraints.
void removeDistanceConstraint(std::size_t idx)
Removes the distance constraint at index idx.
std::size_t getNumDistanceConstraints() const
Returns the number of configured distance constraints.
void setRandomSeed(unsigned int seed)
Sets the seed of the internal random number generator used to initialize the coordinates.
DistanceConstraintList::iterator DistanceConstraintIterator
A mutable iterator over the configured distance constraints.
Definition: DGCoordinatesGenerator.hpp:71
const DistanceConstraint & getDistanceConstraint(std::size_t idx) const
Returns the distance constraint at index idx.
const ValueType & getLearningRateDecrement() const
Returns the currently configured per-cycle learning-rate decrement.
void removeDistanceConstraint(const DistanceConstraintIterator &it)
Removes the distance constraint referenced by iterator it.
ConstDistanceConstraintIterator getDistanceConstraintsBegin() const
Returns a constant iterator pointing to the first distance constraint.
void setLearningRateDecrement(const ValueType &decr)
Sets the per-cycle learning-rate decrement.
DistanceConstraintIterator getDistanceConstraintsEnd()
Returns a mutable iterator pointing one past the last distance constraint.
static constexpr ValueType DEF_LEARNING_RATE_DECREMENT
Default per-cycle decrement subtracted from the learning rate.
Definition: DGCoordinatesGenerator.hpp:106
void generate(std::size_t num_points, CoordsArray &coords)
Generates num_points coordinate vectors that try to satisfy the configured constraints and stores the...
void clearDistanceConstraints()
Removes all configured distance constraints.
static constexpr std::size_t COORDS_DIM
Dimensionality of the coordinate space.
Definition: DGCoordinatesGenerator.hpp:86
static constexpr ValueType DEF_START_LEARNING_RATE
Default initial learning rate.
Definition: DGCoordinatesGenerator.hpp:101
ValueType getDistanceError(const CoordsArray &coords) const
Computes the cumulative squared distance error of coords against the configured distance constraints.
double getCycleStepCountFactor() const
Returns the currently configured per-cycle step-count factor.
void orderDistanceConstraints()
Sorts the configured distance constraints in lexicographic order.
DistanceConstraintIterator getDistanceConstraintsBegin()
Returns a mutable iterator pointing to the first distance constraint.
DGCoordinatesGeneratorBase(const DGCoordinatesGeneratorBase &gen)
DistanceConstraintList::const_iterator ConstDistanceConstraintIterator
A constant iterator over the configured distance constraints.
Definition: DGCoordinatesGenerator.hpp:76
T ValueType
The scalar value type used for coordinates and constraint bounds.
Definition: DGCoordinatesGenerator.hpp:81
ConstDistanceConstraintIterator getDistanceConstraintsEnd() const
Returns a constant iterator pointing one past the last distance constraint.
std::size_t getPoint2Index() const
Returns the index of the second constrained point.
std::size_t getPoint4Index() const
Returns the index of the fourth constrained point.
const ValueType & getLowerBound() const
Returns the lower volume bound.
std::size_t getPoint3Index() const
Returns the index of the third constrained point.
std::size_t getPoint1Index() const
Returns the index of the first constrained point.
VolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx, std::size_t pt4_idx, const ValueType &lb, const ValueType &ub)
Constructs a volume constraint for the tetrahedron spanned by the four points with the given indices.
const ValueType & getUpperBound() const
Returns the upper volume bound.
const VolumeConstraint & getVolumeConstraint(std::size_t idx) const
Returns the volume constraint at index idx.
VolumeConstraintList::iterator VolumeConstraintIterator
A mutable iterator over the configured volume constraints.
Definition: DGCoordinatesGenerator.hpp:407
VolumeConstraintIterator getVolumeConstraintsBegin()
Returns a mutable iterator pointing to the first volume constraint.
VolumeConstraint & getVolumeConstraint(std::size_t idx)
Returns the volume constraint at index idx.
void removeVolumeConstraint(const VolumeConstraintIterator &it)
Removes the volume constraint referenced by iterator it.
ValueType getVolumeError(const CoordsArray &coords) const
Computes the cumulative volume error of coords against the configured volume constraints.
void removeVolumeConstraint(std::size_t idx)
Removes the volume constraint at index idx.
VolumeConstraintList::const_iterator ConstVolumeConstraintIterator
A constant iterator over the configured volume constraints.
Definition: DGCoordinatesGenerator.hpp:412
void addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx, std::size_t pt4_idx, const ValueType &lb, const ValueType &ub)
Appends a new volume constraint to the list of configured constraints.
std::size_t getNumVolumeConstraints() const
Returns the number of configured volume constraints.
ConstVolumeConstraintIterator getVolumeConstraintsBegin() const
Returns a constant iterator pointing to the first volume constraint.
ConstVolumeConstraintIterator getVolumeConstraintsEnd() const
Returns a constant iterator pointing one past the last volume constraint.
void clearVolumeConstraints()
Removes all configured volume constraints.
BaseType::ValueType ValueType
The scalar value type used for coordinates and constraint bounds.
Definition: DGCoordinatesGenerator.hpp:402
VolumeConstraintIterator getVolumeConstraintsEnd()
Returns a mutable iterator pointing one past the last volume constraint.
Generic distance-geometry implementation for the generation of coordinates that fulfill user-provided...
Definition: DGCoordinatesGenerator.hpp:377
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
DGCoordinatesGenerator< 3, double > DG3DCoordinatesGenerator
Convenience alias for the 3D coordinates generator with double-precision values.
Definition: DGCoordinatesGenerator.hpp:581
The namespace of the Chemical Data Processing Library.