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  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
27 #ifndef CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
28 #define CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
29 
30 #include <cstddef>
31 #include <vector>
32 #include <algorithm>
33 #include <cmath>
34 
35 #include <boost/random/mersenne_twister.hpp>
36 #include <boost/random/uniform_real.hpp>
37 #include <boost/random/uniform_int.hpp>
38 
39 #include "CDPL/Base/Exceptions.hpp"
40 
41 
42 namespace CDPL
43 {
44 
45  namespace Util
46  {
47 
55  template <std::size_t Dim, typename T, typename Derived>
57  {
58 
59  public:
60  class DistanceConstraint;
61 
62  private:
63  typedef std::vector<DistanceConstraint> DistanceConstraintList;
64 
65  public:
67  typedef typename DistanceConstraintList::iterator DistanceConstraintIterator;
69  typedef typename DistanceConstraintList::const_iterator ConstDistanceConstraintIterator;
71  typedef T ValueType;
72 
74  static constexpr std::size_t COORDS_DIM = Dim;
76  static constexpr std::size_t DEF_NUM_CYCLES = 50;
78  static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR = 1.0;
80  static constexpr ValueType DEF_START_LEARNING_RATE = 1;
82  static constexpr ValueType DEF_LEARNING_RATE_DECREMENT = 0.95 / 50;
83 
88  {
89 
90  public:
99  DistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
100 
105  std::size_t getPoint1Index() const;
106 
111  std::size_t getPoint2Index() const;
112 
117  const ValueType& getLowerBound() const;
118 
123  const ValueType& getUpperBound() const;
124 
130  bool operator<(const DistanceConstraint& constr) const;
131 
132  private:
133  std::size_t point1Idx;
134  std::size_t point2Idx;
135  ValueType lowerBound;
136  ValueType upperBound;
137  };
138 
143 
151  void addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
152 
157  std::size_t getNumDistanceConstraints() const;
158 
165  const DistanceConstraint& getDistanceConstraint(std::size_t idx) const;
166 
174 
180  void removeDistanceConstraint(std::size_t idx);
181 
188 
194 
200 
206 
212 
217  void setNumCycles(std::size_t num_cycles);
218 
223  void setCycleStepCountFactor(double fact);
224 
229  void setStartLearningRate(const ValueType& rate);
230 
236 
241  std::size_t getNumCycles() const;
242 
247  double getCycleStepCountFactor() const;
248 
254 
260 
265  void setRandomSeed(unsigned int seed);
266 
273  template <typename CoordsArray>
274  void generate(std::size_t num_points, CoordsArray& coords);
275 
282  template <typename CoordsArray>
283  ValueType getDistanceError(const CoordsArray& coords) const;
284 
289 
290  protected:
292 
294 
296 
298 
299  private:
300  std::size_t getNumVolumeConstraints() const;
301 
302  template <typename CoordsArray>
303  void embedCoords(std::size_t num_points, CoordsArray& coords);
304 
305  template <typename CoordsArray>
306  void adjCoordsForDistanceConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
307 
308  template <typename Vec>
309  void adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, const ValueType& lambda) const;
310 
311  template <typename CoordsArray>
312  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
313 
314  template <typename Vec>
315  static ValueType calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
316 
317  typedef boost::random::mt11213b RandNumEngine;
318 
319  std::size_t numCycles;
320  double cycleStepCountFactor;
321  ValueType startLearningRate;
322  ValueType learningRateDecr;
323  DistanceConstraintList distConstraints;
324  RandNumEngine randomEngine;
325  };
326 
327  template <std::size_t Dim, typename T, typename Derived>
329 
330  template <std::size_t Dim, typename T, typename Derived>
332 
333  template <std::size_t Dim, typename T, typename Derived>
335 
336  template <std::size_t Dim, typename T, typename Derived>
339 
340  template <std::size_t Dim, typename T, typename Derived>
343 
344 
351  template <std::size_t Dim, typename T>
352  class DGCoordinatesGenerator : public DGCoordinatesGeneratorBase<Dim, T, DGCoordinatesGenerator<Dim, T> >
353  {};
354 
355 
361  template <typename T>
362  class DGCoordinatesGenerator<3, T> : public DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >
363  {
364 
366  friend class DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >;
367 
368  public:
369  class VolumeConstraint;
370 
371  private:
372  typedef std::vector<VolumeConstraint> VolumeConstraintList;
373 
374  public:
375  typedef typename BaseType::ValueType ValueType;
376  typedef typename VolumeConstraintList::iterator VolumeConstraintIterator;
377  typedef typename VolumeConstraintList::const_iterator ConstVolumeConstraintIterator;
378 
382  class VolumeConstraint
383  {
384 
385  public:
395  VolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
396  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
397 
402  std::size_t getPoint1Index() const;
403 
408  std::size_t getPoint2Index() const;
409 
414  std::size_t getPoint3Index() const;
415 
420  std::size_t getPoint4Index() const;
421 
426  const ValueType& getLowerBound() const;
427 
432  const ValueType& getUpperBound() const;
433 
434  private:
435  std::size_t point1Idx;
436  std::size_t point2Idx;
437  std::size_t point3Idx;
438  std::size_t point4Idx;
439  ValueType lowerBound;
440  ValueType upperBound;
441  };
442 
447 
457  void addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
458  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
459 
464  std::size_t getNumVolumeConstraints() const;
465 
472  const VolumeConstraint& getVolumeConstraint(std::size_t idx) const;
473 
480  VolumeConstraint& getVolumeConstraint(std::size_t idx);
481 
487  void removeVolumeConstraint(std::size_t idx);
488 
495 
501 
507 
513 
519 
526  template <typename CoordsArray>
527  ValueType getVolumeError(const CoordsArray& coords) const;
528 
529  private:
530  template <typename CoordsArray>
531  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
532 
533  template <typename Vec>
534  void adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
535  Vec& pt4_pos, const ValueType& lambda) const;
536 
537  template <typename Vec>
538  static void calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
539 
540  VolumeConstraintList volConstraints;
541  };
542 
545  } // namespace Util
546 } // namespace CDPL
547 
548 
549 // \cond DOC_IMPL_DETAILS
550 // DGCoordinatesGeneratorBase<Dim, T>::DistanceConstraint implementation
551 
552 template <std::size_t Dim, typename T, typename Derived>
554  const ValueType& lb, const ValueType& ub):
555  point1Idx(pt1_idx),
556  point2Idx(pt2_idx), lowerBound(lb), upperBound(ub)
557 {}
558 
559 template <std::size_t Dim, typename T, typename Derived>
561 {
562  return point1Idx;
563 }
564 
565 template <std::size_t Dim, typename T, typename Derived>
567 {
568  return point2Idx;
569 }
570 
571 template <std::size_t Dim, typename T, typename Derived>
573 {
574  return lowerBound;
575 }
576 
577 template <std::size_t Dim, typename T, typename Derived>
579 {
580  return upperBound;
581 }
582 
583 template <std::size_t Dim, typename T, typename Derived>
585 {
586  if (point1Idx < constr.point1Idx)
587  return true;
588 
589  if (point1Idx == constr.point1Idx)
590  return (point2Idx < constr.point2Idx);
591 
592  return false;
593 }
594 
595 
596 // DGCoordinatesGeneratorBase<Dim, T, Derived> implementation
597 
598 template <std::size_t Dim, typename T, typename Derived>
600  numCycles(DEF_NUM_CYCLES), cycleStepCountFactor(DEF_CYCLE_STEP_COUNT_FACTOR), startLearningRate(DEF_START_LEARNING_RATE),
601  learningRateDecr(DEF_LEARNING_RATE_DECREMENT), randomEngine(170375)
602 {}
603 
604 template <std::size_t Dim, typename T, typename Derived>
606  numCycles(gen.numCycles), cycleStepCountFactor(gen.cycleStepCountFactor),
607  startLearningRate(gen.startLearningRate), learningRateDecr(gen.learningRateDecr),
608  distConstraints(gen.distConstraints),
609  randomEngine(gen.randomEngine)
610 {}
611 
612 template <std::size_t Dim, typename T, typename Derived>
614 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::operator=(const DGCoordinatesGeneratorBase& gen)
615 {
616  if (&gen == this)
617  return *this;
618 
619  numCycles = gen.numCycles;
620  cycleStepCountFactor = gen.cycleStepCountFactor;
621  startLearningRate = gen.startLearningRate;
622  learningRateDecr = gen.learningRateDecr;
623  distConstraints = gen.distConstraints;
624  randomEngine = gen.randomEngine;
625 
626  return *this;
627 }
628 
629 template <std::size_t Dim, typename T, typename Derived>
631 {
632  distConstraints.clear();
633 }
634 
635 template <std::size_t Dim, typename T, typename Derived>
636 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx,
637  const ValueType& lb, const ValueType& ub)
638 {
639  distConstraints.push_back(DistanceConstraint(pt1_idx, pt2_idx, lb, ub));
640 }
641 
642 template <std::size_t Dim, typename T, typename Derived>
644 {
645  return distConstraints.size();
646 }
647 
648 template <std::size_t Dim, typename T, typename Derived>
651 {
652  if (idx >= distConstraints.size())
653  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
654 
655  return distConstraints[idx];
656 }
657 
658 template <std::size_t Dim, typename T, typename Derived>
661 {
662  if (idx >= distConstraints.size())
663  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
664 
665  return distConstraints[idx];
666 }
667 
668 template <std::size_t Dim, typename T, typename Derived>
670 {
671  if (idx >= distConstraints.size())
672  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
673 
674  distConstraints.erase(distConstraints.begin() + idx);
675 }
676 
677 template <std::size_t Dim, typename T, typename Derived>
679 {
680  if ((it - distConstraints.begin()) >= distConstraints.size())
681  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint iterator out of bounds");
682 
683  distConstraints.erase(it);
684 }
685 
686 template <std::size_t Dim, typename T, typename Derived>
689 {
690  return distConstraints.begin();
691 }
692 
693 template <std::size_t Dim, typename T, typename Derived>
696 {
697  return distConstraints.end();
698 }
699 
700 template <std::size_t Dim, typename T, typename Derived>
703 {
704  return distConstraints.begin();
705 }
706 
707 template <std::size_t Dim, typename T, typename Derived>
710 {
711  return distConstraints.end();
712 }
713 
714 template <std::size_t Dim, typename T, typename Derived>
716 {
717  numCycles = num_cycles;
718 }
719 
720 template <std::size_t Dim, typename T, typename Derived>
722 {
723  cycleStepCountFactor = fact;
724 }
725 
726 template <std::size_t Dim, typename T, typename Derived>
728 {
729  startLearningRate = rate;
730 }
731 
732 template <std::size_t Dim, typename T, typename Derived>
734 {
735  learningRateDecr = decr;
736 }
737 
738 template <std::size_t Dim, typename T, typename Derived>
740 {
741  return numCycles;
742 }
743 
744 template <std::size_t Dim, typename T, typename Derived>
746 {
747  return cycleStepCountFactor;
748 }
749 
750 template <std::size_t Dim, typename T, typename Derived>
753 {
754  return startLearningRate;
755 }
756 
757 template <std::size_t Dim, typename T, typename Derived>
760 {
761  return learningRateDecr;
762 }
763 
764 template <std::size_t Dim, typename T, typename Derived>
766 {
767  randomEngine.seed(seed);
768 }
769 
770 template <std::size_t Dim, typename T, typename Derived>
771 template <typename CoordsArray>
774 {
775  ValueType error = ValueType();
776  ValueType pos_diff[Dim];
777 
778  for (typename DistanceConstraintList::const_iterator it = distConstraints.begin(), end = distConstraints.end(); it != end; ++it) {
779  const DistanceConstraint& constr = *it;
780 
781  ValueType dist_2 = calcDiffVectorAndSquaredDist(coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], pos_diff);
782  ValueType dist = std::sqrt(dist_2);
783  ValueType lb = constr.getLowerBound();
784  ValueType ub = constr.getUpperBound();
785 
786  if (dist >= lb && dist <= ub)
787  continue;
788 
789  if (dist < lb) {
790  ValueType tmp = (dist_2 - lb * lb) / (0.000001 + lb * lb);
791 
792  error += tmp * tmp;
793 
794  } else {
795  ValueType tmp = (dist_2 - ub * ub) / (0.000001 + ub * ub);
796 
797  error += tmp * tmp;
798  }
799  }
800 
801  return error;
802 }
803 
804 template <std::size_t Dim, typename T, typename Derived>
806 {
807  return 0;
808 }
809 
810 template <std::size_t Dim, typename T, typename Derived>
812 {
813  std::sort(distConstraints.begin(), distConstraints.end());
814 }
815 
816 template <std::size_t Dim, typename T, typename Derived>
817 template <typename CoordsArray>
818 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::generate(std::size_t num_points, CoordsArray& coords)
819 {
820  embedCoords(num_points, coords);
821 }
822 
823 template <std::size_t Dim, typename T, typename Derived>
824 template <typename CoordsArray>
825 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::embedCoords(std::size_t num_points, CoordsArray& coords)
826 {
827  std::size_t num_dist_constrs = distConstraints.size();
828  std::size_t num_vol_constrs = static_cast<Derived&>(*this).getNumVolumeConstraints();
829 
830  if ((num_dist_constrs + num_vol_constrs) == 0)
831  return;
832 
833  std::size_t num_steps = std::size_t((num_dist_constrs + num_vol_constrs) * cycleStepCountFactor);
834  ValueType lambda = startLearningRate;
835 
836  if (num_dist_constrs > 0 && num_vol_constrs > 0) {
837  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs + num_vol_constrs - 1);
838 
839  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr) {
840  for (std::size_t j = 0; j < num_steps; j++) {
841  std::size_t constr_idx = constr_sd(randomEngine);
842 
843  if (constr_idx < num_dist_constrs)
844  adjCoordsForDistanceConstraint(coords, lambda, constr_idx);
845  else
846  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_idx - num_dist_constrs);
847  }
848  }
849 
850  return;
851  }
852 
853  if (num_dist_constrs > 0) {
854  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs - 1);
855 
856  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
857  for (std::size_t j = 0; j < num_steps; j++)
858  adjCoordsForDistanceConstraint(coords, lambda, constr_sd(randomEngine));
859 
860  return;
861  }
862 
863  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_vol_constrs - 1);
864 
865  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
866  for (std::size_t j = 0; j < num_steps; j++)
867  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_sd(randomEngine));
868 }
869 
870 template <std::size_t Dim, typename T, typename Derived>
871 template <typename CoordsArray>
873  std::size_t constr_idx) const
874 {
875  const DistanceConstraint& constr = distConstraints[constr_idx];
876 
877  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], lambda);
878 }
879 
880 template <std::size_t Dim, typename T, typename Derived>
881 template <typename Vec>
882 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos,
883  Vec& pt2_pos, const ValueType& lambda) const
884 {
885  ValueType pos_diff[Dim];
886  ValueType dist = std::sqrt(calcDiffVectorAndSquaredDist(pt1_pos, pt2_pos, pos_diff));
887 
888  ValueType ub = constr.getUpperBound();
889  ValueType lb = constr.getLowerBound();
890 
891  if (dist >= lb && dist <= ub)
892  return;
893 
894  ValueType bound = (dist > ub ? ub : lb);
895  ValueType factor = lambda / 2 * (bound - dist) / (0.000001 + dist);
896 
897  for (std::size_t i = 0; i < Dim; i++) {
898  ValueType pos_delta = pos_diff[i] * factor;
899 
900  pt1_pos[i] -= pos_delta;
901  pt2_pos[i] += pos_delta;
902  }
903 }
904 
905 template <std::size_t Dim, typename T, typename Derived>
906 template <typename CoordsArray>
907 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda,
908  std::size_t constr_idx) const
909 {}
910 
911 template <std::size_t Dim, typename T, typename Derived>
912 template <typename Vec>
914 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
915 {
916  ValueType dist_2 = ValueType();
917 
918  for (std::size_t i = 0; i < Dim; i++) {
919  diff[i] = pt2_pos[i] - pt1_pos[i];
920  dist_2 += diff[i] * diff[i];
921  }
922 
923  return dist_2;
924 }
925 
926 
927 // DGCoordinatesGenerator<3, T>::VolumeConstraint implementation
928 
929 template <typename T>
931  std::size_t pt3_idx, std::size_t pt4_idx,
932  const ValueType& lb, const ValueType& ub):
933  point1Idx(pt1_idx),
934  point2Idx(pt2_idx), point3Idx(pt3_idx), point4Idx(pt4_idx), lowerBound(lb), upperBound(ub)
935 {}
936 
937 template <typename T>
939 {
940  return point1Idx;
941 }
942 
943 template <typename T>
945 {
946  return point2Idx;
947 }
948 
949 template <typename T>
951 {
952  return point3Idx;
953 }
954 
955 template <typename T>
957 {
958  return point4Idx;
959 }
960 
961 template <typename T>
964 {
965  return lowerBound;
966 }
967 
968 template <typename T>
971 {
972  return upperBound;
973 }
974 
975 
976 // DGCoordinatesGenerator<3, T> implementation
977 
978 template <typename T>
980 {
981  volConstraints.clear();
982 }
983 
984 template <typename T>
985 void CDPL::Util::DGCoordinatesGenerator<3, T>::addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
986  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub)
987 {
988  volConstraints.push_back(VolumeConstraint(pt1_idx, pt2_idx, pt3_idx, pt4_idx, lb, ub));
989 }
990 
991 template <typename T>
993 {
994  return volConstraints.size();
995 }
996 
997 template <typename T>
1000 {
1001  if (idx >= volConstraints.size())
1002  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
1003 
1004  return volConstraints[idx];
1005 }
1006 
1007 template <typename T>
1009 {
1010  if (idx >= volConstraints.size())
1011  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
1012 
1013  volConstraints.erase(volConstraints.begin() + idx);
1014 }
1015 
1016 template <typename T>
1017 void CDPL::Util::DGCoordinatesGenerator<3, T>::removeVolumeConstraint(const VolumeConstraintIterator& it)
1018 {
1019  if ((it - volConstraints.begin()) >= volConstraints.size())
1020  throw Base::IndexError("DGCoordinatesGenerator: constraint iterator out of bounds");
1021 
1022  volConstraints.erase(it);
1023 }
1024 
1025 template <typename T>
1028 {
1029  return volConstraints.begin();
1030 }
1031 
1032 template <typename T>
1035 {
1036  return volConstraints.end();
1037 }
1038 
1039 template <typename T>
1042 {
1043  return volConstraints.begin();
1044 }
1045 
1046 template <typename T>
1049 {
1050  return volConstraints.end();
1051 }
1052 
1053 template <typename T>
1054 template <typename CoordsArray>
1056 CDPL::Util::DGCoordinatesGenerator<3, T>::getVolumeError(const CoordsArray& coords) const
1057 {
1058  ValueType error = ValueType();
1059  ValueType v_41[3];
1060  ValueType v_42[3];
1061  ValueType v_43[3];
1062 
1063  for (typename VolumeConstraintList::const_iterator it = volConstraints.begin(), end = volConstraints.end(); it != end; ++it) {
1064  const VolumeConstraint& constr = *it;
1065 
1066  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint1Index()], v_41);
1067  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint2Index()], v_42);
1068  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint3Index()], v_43);
1069 
1070  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;
1071 
1072  ValueType lb = constr.getLowerBound();
1073  ValueType ub = constr.getUpperBound();
1074 
1075  if (vol >= lb && vol <= ub)
1076  continue;
1077 
1078  if (vol < lb) {
1079  ValueType tmp = (vol - lb);
1080 
1081  error += tmp * tmp;
1082 
1083  } else {
1084  ValueType tmp = (vol - ub);
1085 
1086  error += tmp * tmp;
1087  }
1088  }
1089 
1090  return error;
1091 }
1092 
1093 template <typename T>
1094 template <typename CoordsArray>
1095 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const
1096 {
1097  const VolumeConstraint& constr = volConstraints[constr_idx];
1098 
1099  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()],
1100  coords[constr.getPoint3Index()], coords[constr.getPoint4Index()], lambda);
1101 }
1102 
1103 template <typename T>
1104 template <typename Vec>
1105 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
1106  Vec& pt4_pos, const ValueType& lambda) const
1107 {
1108  Vec* pt_pos[4] = {&pt1_pos, &pt2_pos, &pt3_pos, &pt4_pos};
1109  ValueType v_41[3];
1110  ValueType v_42[3];
1111  ValueType v_43[3];
1112 
1113  calcDiffVector(*pt_pos[3], *pt_pos[0], v_41);
1114  calcDiffVector(*pt_pos[3], *pt_pos[1], v_42);
1115  calcDiffVector(*pt_pos[3], *pt_pos[2], v_43);
1116 
1117  ValueType g[4][3];
1118 
1119  g[0][0] = (v_42[1] * v_43[2] - v_42[2] * v_43[1]) / 6;
1120  g[0][1] = -(v_42[0] * v_43[2] - v_42[2] * v_43[0]) / 6;
1121  g[0][2] = (v_42[0] * v_43[1] - v_42[1] * v_43[0]) / 6;
1122 
1123  ValueType vol = (v_41[0] * g[0][0] + v_41[1] * g[0][1] + v_41[2] * g[0][2]);
1124  ValueType ub = constr.getUpperBound();
1125  ValueType lb = constr.getLowerBound();
1126 
1127  if (vol >= lb && vol <= ub)
1128  return;
1129 
1130  g[1][0] = (v_41[2] * v_43[1] - v_41[1] * v_43[2]) / 6;
1131  g[1][1] = (v_41[0] * v_43[2] - v_41[2] * v_43[0]) / 6;
1132  g[1][2] = (v_41[1] * v_43[0] - v_41[0] * v_43[1]) / 6;
1133 
1134  g[2][0] = (v_41[1] * v_42[2] - v_41[2] * v_42[1]) / 6;
1135  g[2][1] = (v_41[2] * v_42[0] - v_41[0] * v_42[2]) / 6;
1136  g[2][2] = (v_41[0] * v_42[1] - v_41[1] * v_42[0]) / 6;
1137 
1138  g[3][0] = -g[0][0] - g[1][0] - g[2][0];
1139  g[3][1] = -g[0][1] - g[1][1] - g[2][1];
1140  g[3][2] = -g[0][2] - g[1][2] - g[2][2];
1141 
1142  ValueType g_len2_sum = ValueType();
1143 
1144  for (std::size_t i = 0; i < 4; i++)
1145  g_len2_sum += g[i][0] * g[i][0] + g[i][1] * g[i][1] + g[i][2] * g[i][2];
1146 
1147  ValueType bound = (vol < lb ? lb : ub);
1148  ValueType fact = lambda * (bound - vol) / g_len2_sum;
1149 
1150  for (std::size_t i = 0; i < 4; i++)
1151  for (std::size_t j = 0; j < 3; j++)
1152  (*pt_pos[i])[j] += fact * g[i][j];
1153 }
1154 
1155 template <typename T>
1156 template <typename Vec>
1157 void CDPL::Util::DGCoordinatesGenerator<3, T>::calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
1158 {
1159  for (std::size_t i = 0; i < 3; i++)
1160  diff[i] = pt2_pos[i] - pt1_pos[i];
1161 }
1162 
1163 // \endcond
1164 
1165 #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:88
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:57
~DGCoordinatesGeneratorBase()
Definition: DGCoordinatesGenerator.hpp:295
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:76
static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR
Default per-cycle step-count multiplier (steps per cycle = factor * number of constraints).
Definition: DGCoordinatesGenerator.hpp:78
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:67
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:82
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:74
static constexpr ValueType DEF_START_LEARNING_RATE
Default initial learning rate.
Definition: DGCoordinatesGenerator.hpp:80
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:69
T ValueType
The scalar value type used for coordinates and constraint bounds.
Definition: DGCoordinatesGenerator.hpp:71
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
Definition: DGCoordinatesGenerator.hpp:376
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
Definition: DGCoordinatesGenerator.hpp:377
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
Definition: DGCoordinatesGenerator.hpp:375
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:353
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:544
The namespace of the Chemical Data Processing Library.