Chemical Data Processing Library C++ API - Version 1.2.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 
52  template <std::size_t Dim, typename T, typename Derived>
54  {
55 
56  public:
57  class DistanceConstraint;
58 
59  private:
60  typedef std::vector<DistanceConstraint> DistanceConstraintList;
61 
62  public:
63  typedef typename DistanceConstraintList::iterator DistanceConstraintIterator;
64  typedef typename DistanceConstraintList::const_iterator ConstDistanceConstraintIterator;
65  typedef T ValueType;
66 
67  static constexpr std::size_t COORDS_DIM = Dim;
68  static constexpr std::size_t DEF_NUM_CYCLES = 50;
69  static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR = 1.0;
70  static constexpr ValueType DEF_START_LEARNING_RATE = 1;
71  static constexpr ValueType DEF_LEARNING_RATE_DECREMENT = 0.95 / 50;
72 
74  {
75 
76  public:
77  DistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
78 
79  std::size_t getPoint1Index() const;
80 
81  std::size_t getPoint2Index() const;
82 
83  const ValueType& getLowerBound() const;
84 
85  const ValueType& getUpperBound() const;
86 
87  bool operator<(const DistanceConstraint& constr) const;
88 
89  private:
90  std::size_t point1Idx;
91  std::size_t point2Idx;
92  ValueType lowerBound;
93  ValueType upperBound;
94  };
95 
97 
98  void addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType& lb, const ValueType& ub);
99 
100  std::size_t getNumDistanceConstraints() const;
101 
102  const DistanceConstraint& getDistanceConstraint(std::size_t idx) const;
103 
105 
106  void removeDistanceConstraint(std::size_t idx);
107 
109 
111 
113 
115 
117 
118  void setNumCycles(std::size_t num_cycles);
119 
120  void setCycleStepCountFactor(double fact);
121 
122  void setStartLearningRate(const ValueType& rate);
123 
125 
126  std::size_t getNumCycles() const;
127 
128  double getCycleStepCountFactor() const;
129 
131 
133 
134  void setRandomSeed(unsigned int seed);
135 
136  template <typename CoordsArray>
137  void generate(std::size_t num_points, CoordsArray& coords);
138 
139  template <typename CoordsArray>
140  ValueType getDistanceError(const CoordsArray& coords) const;
141 
143 
144  protected:
146 
148 
150 
152 
153  private:
154  std::size_t getNumVolumeConstraints() const;
155 
156  template <typename CoordsArray>
157  void embedCoords(std::size_t num_points, CoordsArray& coords);
158 
159  template <typename CoordsArray>
160  void adjCoordsForDistanceConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
161 
162  template <typename Vec>
163  void adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, const ValueType& lambda) const;
164 
165  template <typename CoordsArray>
166  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
167 
168  template <typename Vec>
169  static ValueType calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
170 
171  typedef boost::random::mt11213b RandNumEngine;
172 
173  std::size_t numCycles;
174  double cycleStepCountFactor;
175  ValueType startLearningRate;
176  ValueType learningRateDecr;
177  DistanceConstraintList distConstraints;
178  RandNumEngine randomEngine;
179  };
180 
181  template <std::size_t Dim, typename T, typename Derived>
183 
184  template <std::size_t Dim, typename T, typename Derived>
186 
187  template <std::size_t Dim, typename T, typename Derived>
189 
190  template <std::size_t Dim, typename T, typename Derived>
193 
194  template <std::size_t Dim, typename T, typename Derived>
197 
198 
202  template <std::size_t Dim, typename T>
203  class DGCoordinatesGenerator : public DGCoordinatesGeneratorBase<Dim, T, DGCoordinatesGenerator<Dim, T> >
204  {};
205 
206 
210  template <typename T>
211  class DGCoordinatesGenerator<3, T> : public DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >
212  {
213 
215  friend class DGCoordinatesGeneratorBase<3, T, DGCoordinatesGenerator<3, T> >;
216 
217  public:
218  class VolumeConstraint;
219 
220  private:
221  typedef std::vector<VolumeConstraint> VolumeConstraintList;
222 
223  public:
224  typedef typename BaseType::ValueType ValueType;
225  typedef typename VolumeConstraintList::iterator VolumeConstraintIterator;
226  typedef typename VolumeConstraintList::const_iterator ConstVolumeConstraintIterator;
227 
228  class VolumeConstraint
229  {
230 
231  public:
232  VolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
233  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
234 
235  std::size_t getPoint1Index() const;
236 
237  std::size_t getPoint2Index() const;
238 
239  std::size_t getPoint3Index() const;
240 
241  std::size_t getPoint4Index() const;
242 
243  const ValueType& getLowerBound() const;
244 
245  const ValueType& getUpperBound() const;
246 
247  private:
248  std::size_t point1Idx;
249  std::size_t point2Idx;
250  std::size_t point3Idx;
251  std::size_t point4Idx;
252  ValueType lowerBound;
253  ValueType upperBound;
254  };
255 
257 
258  void addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
259  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub);
260 
261  std::size_t getNumVolumeConstraints() const;
262 
263  const VolumeConstraint& getVolumeConstraint(std::size_t idx) const;
264 
265  VolumeConstraint& getVolumeConstraint(std::size_t idx);
266 
267  void removeVolumeConstraint(std::size_t idx);
268 
270 
272 
274 
276 
278 
279  template <typename CoordsArray>
280  ValueType getVolumeError(const CoordsArray& coords) const;
281 
282  private:
283  template <typename CoordsArray>
284  void adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const;
285 
286  template <typename Vec>
287  void adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
288  Vec& pt4_pos, const ValueType& lambda) const;
289 
290  template <typename Vec>
291  static void calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[]);
292 
293  VolumeConstraintList volConstraints;
294  };
295 
297  } // namespace Util
298 } // namespace CDPL
299 
300 
301 // \cond DOC_IMPL_DETAILS
302 // DGCoordinatesGeneratorBase<Dim, T>::DistanceConstraint implementation
303 
304 template <std::size_t Dim, typename T, typename Derived>
306  const ValueType& lb, const ValueType& ub):
307  point1Idx(pt1_idx),
308  point2Idx(pt2_idx), lowerBound(lb), upperBound(ub)
309 {}
310 
311 template <std::size_t Dim, typename T, typename Derived>
313 {
314  return point1Idx;
315 }
316 
317 template <std::size_t Dim, typename T, typename Derived>
319 {
320  return point2Idx;
321 }
322 
323 template <std::size_t Dim, typename T, typename Derived>
325 {
326  return lowerBound;
327 }
328 
329 template <std::size_t Dim, typename T, typename Derived>
331 {
332  return upperBound;
333 }
334 
335 template <std::size_t Dim, typename T, typename Derived>
337 {
338  if (point1Idx < constr.point1Idx)
339  return true;
340 
341  if (point1Idx == constr.point1Idx)
342  return (point2Idx < constr.point2Idx);
343 
344  return false;
345 }
346 
347 
348 // DGCoordinatesGeneratorBase<Dim, T, Derived> implementation
349 
350 template <std::size_t Dim, typename T, typename Derived>
352  numCycles(DEF_NUM_CYCLES), cycleStepCountFactor(DEF_CYCLE_STEP_COUNT_FACTOR), startLearningRate(DEF_START_LEARNING_RATE),
353  learningRateDecr(DEF_LEARNING_RATE_DECREMENT), randomEngine(170375)
354 {}
355 
356 template <std::size_t Dim, typename T, typename Derived>
358  numCycles(gen.numCycles), cycleStepCountFactor(gen.cycleStepCountFactor),
359  startLearningRate(gen.startLearningRate), learningRateDecr(gen.learningRateDecr),
360  distConstraints(gen.distConstraints),
361  randomEngine(gen.randomEngine)
362 {}
363 
364 template <std::size_t Dim, typename T, typename Derived>
366 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::operator=(const DGCoordinatesGeneratorBase& gen)
367 {
368  if (&gen == this)
369  return *this;
370 
371  numCycles = gen.numCycles;
372  cycleStepCountFactor = gen.cycleStepCountFactor;
373  startLearningRate = gen.startLearningRate;
374  learningRateDecr = gen.learningRateDecr;
375  distConstraints = gen.distConstraints;
376  randomEngine = gen.randomEngine;
377 
378  return *this;
379 }
380 
381 template <std::size_t Dim, typename T, typename Derived>
383 {
384  distConstraints.clear();
385 }
386 
387 template <std::size_t Dim, typename T, typename Derived>
388 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx,
389  const ValueType& lb, const ValueType& ub)
390 {
391  distConstraints.push_back(DistanceConstraint(pt1_idx, pt2_idx, lb, ub));
392 }
393 
394 template <std::size_t Dim, typename T, typename Derived>
396 {
397  return distConstraints.size();
398 }
399 
400 template <std::size_t Dim, typename T, typename Derived>
403 {
404  if (idx >= distConstraints.size())
405  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
406 
407  return distConstraints[idx];
408 }
409 
410 template <std::size_t Dim, typename T, typename Derived>
413 {
414  if (idx >= distConstraints.size())
415  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
416 
417  return distConstraints[idx];
418 }
419 
420 template <std::size_t Dim, typename T, typename Derived>
422 {
423  if (idx >= distConstraints.size())
424  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint index out of bounds");
425 
426  distConstraints.erase(distConstraints.begin() + idx);
427 }
428 
429 template <std::size_t Dim, typename T, typename Derived>
431 {
432  if ((it - distConstraints.begin()) >= distConstraints.size())
433  throw Base::IndexError("DGCoordinatesGeneratorBase: constraint iterator out of bounds");
434 
435  distConstraints.erase(it);
436 }
437 
438 template <std::size_t Dim, typename T, typename Derived>
441 {
442  return distConstraints.begin();
443 }
444 
445 template <std::size_t Dim, typename T, typename Derived>
448 {
449  return distConstraints.end();
450 }
451 
452 template <std::size_t Dim, typename T, typename Derived>
455 {
456  return distConstraints.begin();
457 }
458 
459 template <std::size_t Dim, typename T, typename Derived>
462 {
463  return distConstraints.end();
464 }
465 
466 template <std::size_t Dim, typename T, typename Derived>
468 {
469  numCycles = num_cycles;
470 }
471 
472 template <std::size_t Dim, typename T, typename Derived>
474 {
475  cycleStepCountFactor = fact;
476 }
477 
478 template <std::size_t Dim, typename T, typename Derived>
480 {
481  startLearningRate = rate;
482 }
483 
484 template <std::size_t Dim, typename T, typename Derived>
486 {
487  learningRateDecr = decr;
488 }
489 
490 template <std::size_t Dim, typename T, typename Derived>
492 {
493  return numCycles;
494 }
495 
496 template <std::size_t Dim, typename T, typename Derived>
498 {
499  return cycleStepCountFactor;
500 }
501 
502 template <std::size_t Dim, typename T, typename Derived>
505 {
506  return startLearningRate;
507 }
508 
509 template <std::size_t Dim, typename T, typename Derived>
512 {
513  return learningRateDecr;
514 }
515 
516 template <std::size_t Dim, typename T, typename Derived>
518 {
519  randomEngine.seed(seed);
520 }
521 
522 template <std::size_t Dim, typename T, typename Derived>
523 template <typename CoordsArray>
526 {
527  ValueType error = ValueType();
528  ValueType pos_diff[Dim];
529 
530  for (typename DistanceConstraintList::const_iterator it = distConstraints.begin(), end = distConstraints.end(); it != end; ++it) {
531  const DistanceConstraint& constr = *it;
532 
533  ValueType dist_2 = calcDiffVectorAndSquaredDist(coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], pos_diff);
534  ValueType dist = std::sqrt(dist_2);
535  ValueType lb = constr.getLowerBound();
536  ValueType ub = constr.getUpperBound();
537 
538  if (dist >= lb && dist <= ub)
539  continue;
540 
541  if (dist < lb) {
542  ValueType tmp = (dist_2 - lb * lb) / (0.000001 + lb * lb);
543 
544  error += tmp * tmp;
545 
546  } else {
547  ValueType tmp = (dist_2 - ub * ub) / (0.000001 + ub * ub);
548 
549  error += tmp * tmp;
550  }
551  }
552 
553  return error;
554 }
555 
556 template <std::size_t Dim, typename T, typename Derived>
558 {
559  return 0;
560 }
561 
562 template <std::size_t Dim, typename T, typename Derived>
564 {
565  std::sort(distConstraints.begin(), distConstraints.end());
566 }
567 
568 template <std::size_t Dim, typename T, typename Derived>
569 template <typename CoordsArray>
570 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::generate(std::size_t num_points, CoordsArray& coords)
571 {
572  embedCoords(num_points, coords);
573 }
574 
575 template <std::size_t Dim, typename T, typename Derived>
576 template <typename CoordsArray>
577 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::embedCoords(std::size_t num_points, CoordsArray& coords)
578 {
579  std::size_t num_dist_constrs = distConstraints.size();
580  std::size_t num_vol_constrs = static_cast<Derived&>(*this).getNumVolumeConstraints();
581 
582  if ((num_dist_constrs + num_vol_constrs) == 0)
583  return;
584 
585  std::size_t num_steps = std::size_t((num_dist_constrs + num_vol_constrs) * cycleStepCountFactor);
586  ValueType lambda = startLearningRate;
587 
588  if (num_dist_constrs > 0 && num_vol_constrs > 0) {
589  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs + num_vol_constrs - 1);
590 
591  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr) {
592  for (std::size_t j = 0; j < num_steps; j++) {
593  std::size_t constr_idx = constr_sd(randomEngine);
594 
595  if (constr_idx < num_dist_constrs)
596  adjCoordsForDistanceConstraint(coords, lambda, constr_idx);
597  else
598  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_idx - num_dist_constrs);
599  }
600  }
601 
602  return;
603  }
604 
605  if (num_dist_constrs > 0) {
606  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_dist_constrs - 1);
607 
608  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
609  for (std::size_t j = 0; j < num_steps; j++)
610  adjCoordsForDistanceConstraint(coords, lambda, constr_sd(randomEngine));
611 
612  return;
613  }
614 
615  boost::random::uniform_int_distribution<std::size_t> constr_sd(0, num_vol_constrs - 1);
616 
617  for (std::size_t i = 0; i < numCycles; i++, lambda -= learningRateDecr)
618  for (std::size_t j = 0; j < num_steps; j++)
619  static_cast<Derived&>(*this).template adjCoordsForVolumeConstraint<CoordsArray>(coords, lambda, constr_sd(randomEngine));
620 }
621 
622 template <std::size_t Dim, typename T, typename Derived>
623 template <typename CoordsArray>
625  std::size_t constr_idx) const
626 {
627  const DistanceConstraint& constr = distConstraints[constr_idx];
628 
629  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()], lambda);
630 }
631 
632 template <std::size_t Dim, typename T, typename Derived>
633 template <typename Vec>
634 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForConstraint(const DistanceConstraint& constr, Vec& pt1_pos,
635  Vec& pt2_pos, const ValueType& lambda) const
636 {
637  ValueType pos_diff[Dim];
638  ValueType dist = std::sqrt(calcDiffVectorAndSquaredDist(pt1_pos, pt2_pos, pos_diff));
639 
640  ValueType ub = constr.getUpperBound();
641  ValueType lb = constr.getLowerBound();
642 
643  if (dist >= lb && dist <= ub)
644  return;
645 
646  ValueType bound = (dist > ub ? ub : lb);
647  ValueType factor = lambda / 2 * (bound - dist) / (0.000001 + dist);
648 
649  for (std::size_t i = 0; i < Dim; i++) {
650  ValueType pos_delta = pos_diff[i] * factor;
651 
652  pt1_pos[i] -= pos_delta;
653  pt2_pos[i] += pos_delta;
654  }
655 }
656 
657 template <std::size_t Dim, typename T, typename Derived>
658 template <typename CoordsArray>
659 void CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda,
660  std::size_t constr_idx) const
661 {}
662 
663 template <std::size_t Dim, typename T, typename Derived>
664 template <typename Vec>
666 CDPL::Util::DGCoordinatesGeneratorBase<Dim, T, Derived>::calcDiffVectorAndSquaredDist(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
667 {
668  ValueType dist_2 = ValueType();
669 
670  for (std::size_t i = 0; i < Dim; i++) {
671  diff[i] = pt2_pos[i] - pt1_pos[i];
672  dist_2 += diff[i] * diff[i];
673  }
674 
675  return dist_2;
676 }
677 
678 
679 // DGCoordinatesGenerator<3, T>::VolumeConstraint implementation
680 
681 template <typename T>
683  std::size_t pt3_idx, std::size_t pt4_idx,
684  const ValueType& lb, const ValueType& ub):
685  point1Idx(pt1_idx),
686  point2Idx(pt2_idx), point3Idx(pt3_idx), point4Idx(pt4_idx), lowerBound(lb), upperBound(ub)
687 {}
688 
689 template <typename T>
691 {
692  return point1Idx;
693 }
694 
695 template <typename T>
697 {
698  return point2Idx;
699 }
700 
701 template <typename T>
703 {
704  return point3Idx;
705 }
706 
707 template <typename T>
709 {
710  return point4Idx;
711 }
712 
713 template <typename T>
716 {
717  return lowerBound;
718 }
719 
720 template <typename T>
723 {
724  return upperBound;
725 }
726 
727 
728 // DGCoordinatesGenerator<3, T> implementation
729 
730 template <typename T>
732 {
733  volConstraints.clear();
734 }
735 
736 template <typename T>
737 void CDPL::Util::DGCoordinatesGenerator<3, T>::addVolumeConstraint(std::size_t pt1_idx, std::size_t pt2_idx, std::size_t pt3_idx,
738  std::size_t pt4_idx, const ValueType& lb, const ValueType& ub)
739 {
740  volConstraints.push_back(VolumeConstraint(pt1_idx, pt2_idx, pt3_idx, pt4_idx, lb, ub));
741 }
742 
743 template <typename T>
745 {
746  return volConstraints.size();
747 }
748 
749 template <typename T>
752 {
753  if (idx >= volConstraints.size())
754  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
755 
756  return volConstraints[idx];
757 }
758 
759 template <typename T>
761 {
762  if (idx >= volConstraints.size())
763  throw Base::IndexError("DGCoordinatesGenerator: constraint index out of bounds");
764 
765  volConstraints.erase(volConstraints.begin() + idx);
766 }
767 
768 template <typename T>
769 void CDPL::Util::DGCoordinatesGenerator<3, T>::removeVolumeConstraint(const VolumeConstraintIterator& it)
770 {
771  if ((it - volConstraints.begin()) >= volConstraints.size())
772  throw Base::IndexError("DGCoordinatesGenerator: constraint iterator out of bounds");
773 
774  volConstraints.erase(it);
775 }
776 
777 template <typename T>
780 {
781  return volConstraints.begin();
782 }
783 
784 template <typename T>
787 {
788  return volConstraints.end();
789 }
790 
791 template <typename T>
794 {
795  return volConstraints.begin();
796 }
797 
798 template <typename T>
801 {
802  return volConstraints.end();
803 }
804 
805 template <typename T>
806 template <typename CoordsArray>
808 CDPL::Util::DGCoordinatesGenerator<3, T>::getVolumeError(const CoordsArray& coords) const
809 {
810  ValueType error = ValueType();
811  ValueType v_41[3];
812  ValueType v_42[3];
813  ValueType v_43[3];
814 
815  for (typename VolumeConstraintList::const_iterator it = volConstraints.begin(), end = volConstraints.end(); it != end; ++it) {
816  const VolumeConstraint& constr = *it;
817 
818  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint1Index()], v_41);
819  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint2Index()], v_42);
820  calcDiffVector(coords[constr.getPoint4Index()], coords[constr.getPoint3Index()], v_43);
821 
822  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;
823 
824  ValueType lb = constr.getLowerBound();
825  ValueType ub = constr.getUpperBound();
826 
827  if (vol >= lb && vol <= ub)
828  continue;
829 
830  if (vol < lb) {
831  ValueType tmp = (vol - lb);
832 
833  error += tmp * tmp;
834 
835  } else {
836  ValueType tmp = (vol - ub);
837 
838  error += tmp * tmp;
839  }
840  }
841 
842  return error;
843 }
844 
845 template <typename T>
846 template <typename CoordsArray>
847 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForVolumeConstraint(CoordsArray& coords, const ValueType& lambda, std::size_t constr_idx) const
848 {
849  const VolumeConstraint& constr = volConstraints[constr_idx];
850 
851  adjCoordsForConstraint(constr, coords[constr.getPoint1Index()], coords[constr.getPoint2Index()],
852  coords[constr.getPoint3Index()], coords[constr.getPoint4Index()], lambda);
853 }
854 
855 template <typename T>
856 template <typename Vec>
857 void CDPL::Util::DGCoordinatesGenerator<3, T>::adjCoordsForConstraint(const VolumeConstraint& constr, Vec& pt1_pos, Vec& pt2_pos, Vec& pt3_pos,
858  Vec& pt4_pos, const ValueType& lambda) const
859 {
860  Vec* pt_pos[4] = {&pt1_pos, &pt2_pos, &pt3_pos, &pt4_pos};
861  ValueType v_41[3];
862  ValueType v_42[3];
863  ValueType v_43[3];
864 
865  calcDiffVector(*pt_pos[3], *pt_pos[0], v_41);
866  calcDiffVector(*pt_pos[3], *pt_pos[1], v_42);
867  calcDiffVector(*pt_pos[3], *pt_pos[2], v_43);
868 
869  ValueType g[4][3];
870 
871  g[0][0] = (v_42[1] * v_43[2] - v_42[2] * v_43[1]) / 6;
872  g[0][1] = -(v_42[0] * v_43[2] - v_42[2] * v_43[0]) / 6;
873  g[0][2] = (v_42[0] * v_43[1] - v_42[1] * v_43[0]) / 6;
874 
875  ValueType vol = (v_41[0] * g[0][0] + v_41[1] * g[0][1] + v_41[2] * g[0][2]);
876  ValueType ub = constr.getUpperBound();
877  ValueType lb = constr.getLowerBound();
878 
879  if (vol >= lb && vol <= ub)
880  return;
881 
882  g[1][0] = (v_41[2] * v_43[1] - v_41[1] * v_43[2]) / 6;
883  g[1][1] = (v_41[0] * v_43[2] - v_41[2] * v_43[0]) / 6;
884  g[1][2] = (v_41[1] * v_43[0] - v_41[0] * v_43[1]) / 6;
885 
886  g[2][0] = (v_41[1] * v_42[2] - v_41[2] * v_42[1]) / 6;
887  g[2][1] = (v_41[2] * v_42[0] - v_41[0] * v_42[2]) / 6;
888  g[2][2] = (v_41[0] * v_42[1] - v_41[1] * v_42[0]) / 6;
889 
890  g[3][0] = -g[0][0] - g[1][0] - g[2][0];
891  g[3][1] = -g[0][1] - g[1][1] - g[2][1];
892  g[3][2] = -g[0][2] - g[1][2] - g[2][2];
893 
894  ValueType g_len2_sum = ValueType();
895 
896  for (std::size_t i = 0; i < 4; i++)
897  g_len2_sum += g[i][0] * g[i][0] + g[i][1] * g[i][1] + g[i][2] * g[i][2];
898 
899  ValueType bound = (vol < lb ? lb : ub);
900  ValueType fact = lambda * (bound - vol) / g_len2_sum;
901 
902  for (std::size_t i = 0; i < 4; i++)
903  for (std::size_t j = 0; j < 3; j++)
904  (*pt_pos[i])[j] += fact * g[i][j];
905 }
906 
907 template <typename T>
908 template <typename Vec>
909 void CDPL::Util::DGCoordinatesGenerator<3, T>::calcDiffVector(const Vec& pt1_pos, const Vec& pt2_pos, ValueType diff[])
910 {
911  for (std::size_t i = 0; i < 3; i++)
912  diff[i] = pt2_pos[i] - pt1_pos[i];
913 }
914 
915 // \endcond
916 
917 #endif // CDPL_UTIL_DGCOORDINATESGENERATOR_HPP
Definition of exception classes.
Definition: DGCoordinatesGenerator.hpp:74
bool operator<(const DistanceConstraint &constr) const
DistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType &lb, const ValueType &ub)
Base for classes dedicated to the generation of coordinates that fulfill user-provided point distance...
Definition: DGCoordinatesGenerator.hpp:54
~DGCoordinatesGeneratorBase()
Definition: DGCoordinatesGenerator.hpp:149
void setNumCycles(std::size_t num_cycles)
DGCoordinatesGeneratorBase & operator=(const DGCoordinatesGeneratorBase &gen)
const ValueType & getStartLearningRate() const
void setStartLearningRate(const ValueType &rate)
DistanceConstraint & getDistanceConstraint(std::size_t idx)
static constexpr std::size_t DEF_NUM_CYCLES
Definition: DGCoordinatesGenerator.hpp:68
static constexpr double DEF_CYCLE_STEP_COUNT_FACTOR
Definition: DGCoordinatesGenerator.hpp:69
void addDistanceConstraint(std::size_t pt1_idx, std::size_t pt2_idx, const ValueType &lb, const ValueType &ub)
void removeDistanceConstraint(std::size_t idx)
std::size_t getNumDistanceConstraints() const
void setRandomSeed(unsigned int seed)
DistanceConstraintList::iterator DistanceConstraintIterator
Definition: DGCoordinatesGenerator.hpp:63
const DistanceConstraint & getDistanceConstraint(std::size_t idx) const
const ValueType & getLearningRateDecrement() const
void removeDistanceConstraint(const DistanceConstraintIterator &it)
ConstDistanceConstraintIterator getDistanceConstraintsBegin() const
void setLearningRateDecrement(const ValueType &decr)
DistanceConstraintIterator getDistanceConstraintsEnd()
static constexpr ValueType DEF_LEARNING_RATE_DECREMENT
Definition: DGCoordinatesGenerator.hpp:71
void generate(std::size_t num_points, CoordsArray &coords)
static constexpr std::size_t COORDS_DIM
Definition: DGCoordinatesGenerator.hpp:67
static constexpr ValueType DEF_START_LEARNING_RATE
Definition: DGCoordinatesGenerator.hpp:70
ValueType getDistanceError(const CoordsArray &coords) const
DistanceConstraintIterator getDistanceConstraintsBegin()
DGCoordinatesGeneratorBase(const DGCoordinatesGeneratorBase &gen)
DistanceConstraintList::const_iterator ConstDistanceConstraintIterator
Definition: DGCoordinatesGenerator.hpp:64
T ValueType
Definition: DGCoordinatesGenerator.hpp:65
ConstDistanceConstraintIterator getDistanceConstraintsEnd() const
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)
const VolumeConstraint & getVolumeConstraint(std::size_t idx) const
VolumeConstraintList::iterator VolumeConstraintIterator
Definition: DGCoordinatesGenerator.hpp:225
VolumeConstraintIterator getVolumeConstraintsBegin()
VolumeConstraint & getVolumeConstraint(std::size_t idx)
void removeVolumeConstraint(const VolumeConstraintIterator &it)
ValueType getVolumeError(const CoordsArray &coords) const
void removeVolumeConstraint(std::size_t idx)
VolumeConstraintList::const_iterator ConstVolumeConstraintIterator
Definition: DGCoordinatesGenerator.hpp:226
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)
ConstVolumeConstraintIterator getVolumeConstraintsBegin() const
ConstVolumeConstraintIterator getVolumeConstraintsEnd() const
BaseType::ValueType ValueType
Definition: DGCoordinatesGenerator.hpp:224
VolumeConstraintIterator getVolumeConstraintsEnd()
Generic implementation for generation of coordinates that fulfill user-provided point distance constr...
Definition: DGCoordinatesGenerator.hpp:204
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
DGCoordinatesGenerator< 3, double > DG3DCoordinatesGenerator
Definition: DGCoordinatesGenerator.hpp:296
The namespace of the Chemical Data Processing Library.