Molassembler  1.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Properties.h
Go to the documentation of this file.
1 
16 #ifndef INCLUDE_SHAPE_CONSTEXPR_PROPERTIES_H
17 #define INCLUDE_SHAPE_CONSTEXPR_PROPERTIES_H
18 
21 
27 
28 namespace Scine {
29 namespace Molassembler {
30 namespace Shapes {
31 
48 namespace ConstexprProperties {
49 
50 constexpr double floatingPointEqualityTolerance = 1e-4;
51 
58 template<typename ShapeClass>
59 constexpr double calculateSmallestAngle() {
60  double smallestAngle = M_PI;
61 
62  for(unsigned i = 0; i < ShapeClass::size; ++i) {
63  for(unsigned j = i + 1; j < ShapeClass::size; ++j) {
64  double returnedAngle = ShapeClass::angleFunction(i, j);
65  if(returnedAngle < smallestAngle) {
66  smallestAngle = returnedAngle;
67  }
68  }
69  }
70 
71  return smallestAngle;
72 }
73 
80 template<typename ShapeClass>
86  static constexpr std::pair<double, double> value() {
87  double smallestAngle = M_PI;
88  double largestAngle = 0;
89 
90  for(unsigned i = 0; i < ShapeClass::size; ++i) {
91  for(unsigned j = i + 1; j < ShapeClass::size; ++j) {
92  double returnedAngle = ShapeClass::angleFunction(i, j);
93  if(returnedAngle < smallestAngle) {
94  smallestAngle = returnedAngle;
95  }
96 
97  if(returnedAngle > largestAngle) {
98  largestAngle = returnedAngle;
99  }
100  }
101  }
102 
103  return {smallestAngle, largestAngle};
104  }
105 };
106 
113 template<typename ... ShapeClass>
119  static constexpr double value() {
120  const std::array<double, sizeof...(ShapeClass)> smallestAngles {{
121  calculateSmallestAngle<ShapeClass>()...
122  }};
123 
124  // C++17 min_element (isn't constexpr before)
125  double minElement = smallestAngles.at(0);
126 
127  for(unsigned i = 1; i < sizeof...(ShapeClass); ++i) {
128  if(smallestAngles.at(i) < minElement) {
129  minElement = smallestAngles.at(i);
130  }
131  }
132 
133  return minElement;
134  }
135 };
136 
142 template<typename T, size_t size>
144 
146 template<typename ShapeClass>
147 constexpr auto startingIndexSequence() {
148  return Temple::iota<ArrayType, unsigned, ShapeClass::size>();
149 }
150 
152 template<typename ShapeClass, size_t... Indices>
155  const unsigned rotationFunctionIndex,
156  std::index_sequence<Indices...> /* inds */
157 ) {
158  return {
159  indices.at(
160  ShapeClass::rotations.at(rotationFunctionIndex).at(Indices)
161  )...
162  };
163 }
164 
169 template<typename ShapeClass>
172  const unsigned rotationFunctionIndex
173 ) {
174  return applyRotationImpl<ShapeClass>(
175  indices,
176  rotationFunctionIndex,
177  std::make_index_sequence<ShapeClass::size>{}
178  );
179 }
180 
182 template<typename ShapeClass, unsigned rotationFunctionIndex>
183 constexpr unsigned rotationPeriodicityImpl(
184  const ArrayType<unsigned, ShapeClass::size>& runningIndices,
185  const unsigned count
186 ) {
187  if(
189  runningIndices,
190  startingIndexSequence<ShapeClass>()
191  )
192  ) {
193  return count;
194  }
195 
196  return rotationPeriodicityImpl<ShapeClass, rotationFunctionIndex>(
197  applyRotation<ShapeClass>(
198  runningIndices,
199  rotationFunctionIndex
200  ),
201  count + 1
202  );
203 }
204 
215 template<typename ShapeClass, unsigned rotationFunctionIndex>
216 constexpr unsigned rotationPeriodicity() {
217  return rotationPeriodicityImpl<ShapeClass, rotationFunctionIndex>(
218  applyRotation<ShapeClass>(
219  startingIndexSequence<ShapeClass>(),
220  rotationFunctionIndex
221  ),
222  1
223  );
224 }
225 
227 template<typename ShapeClass, size_t ...Inds>
228 constexpr ArrayType<unsigned, ShapeClass::rotations.size()>
229 rotationPeriodicitiesImpl(std::index_sequence<Inds...> /* inds */) {
230  return { rotationPeriodicity<ShapeClass, Inds>()... };
231 }
232 
234 template<typename ShapeClass>
236  return rotationPeriodicitiesImpl<ShapeClass>(
237  std::make_index_sequence<ShapeClass::rotations.size()>{}
238  );
239 }
240 
252 template<typename ShapeClass>
254  static constexpr ArrayType<
255  unsigned,
257  > value = rotationPeriodicitiesImpl<ShapeClass>(
258  std::make_index_sequence<ShapeClass::rotations.size()>{}
259  );
260 };
261 
263 template<typename ... ShapeClasses>
265  static constexpr unsigned value() {
266  ArrayType<unsigned, sizeof...(ShapeClasses)> sizes {
268  };
269 
270  return Temple::max(sizes);
271  }
272 };
273 
278 >();
279 
287 template<typename ShapeClass>
288 constexpr Temple::Vector getCoordinates(const unsigned indexInSymmetry) {
289  if(indexInSymmetry != ORIGIN_PLACEHOLDER) {
290  return ShapeClass::coordinates.at(indexInSymmetry);
291  }
292 
293  return {0, 0, 0};
294 }
295 
301 constexpr double getTetrahedronVolume(
302  const Temple::Vector& i,
303  const Temple::Vector& j,
304  const Temple::Vector& k,
305  const Temple::Vector& l
306 ) {
307  return (i - l).dot(
308  (j - l).cross(k - l)
309  );
310 }
311 
312 // Typedef to avoid reusing C-Style function ptr type
313 using AngleFunctionPtr = double(*)(const unsigned, const unsigned);
314 
325 template<size_t size>
326 constexpr double calculateAngularDistortion(
327  const ArrayType<unsigned, size>& indexMapping,
328  const size_t sourceSymmetrySize,
329  const AngleFunctionPtr sourceAngleFunction,
330  const AngleFunctionPtr targetAngleFunction
331 ) {
332  double distortionSum = 0;
333 
334  for(unsigned i = 0; i < sourceSymmetrySize; ++i) {
335  for(unsigned j = i + 1; j < sourceSymmetrySize; ++j) {
336  distortionSum += Temple::Math::abs(
337  sourceAngleFunction(i, j)
338  - targetAngleFunction(
339  indexMapping.at(i),
340  indexMapping.at(j)
341  )
342  );
343  }
344  }
345 
346  return distortionSum;
347 }
348 
360 template<size_t size>
361 constexpr unsigned propagateSymmetryPosition(
362  const unsigned symmetryPosition,
363  const ArrayType<unsigned, size>& indexMapping
364 ) {
365  if(symmetryPosition != ORIGIN_PLACEHOLDER) {
366  return indexMapping.at(symmetryPosition);
367  }
368 
369  return ORIGIN_PLACEHOLDER;
370 }
371 
383 template<typename ShapeClassFrom, typename ShapeClassTo>
384 constexpr double calculateChiralDistortion(
385  const ArrayType<
386  unsigned,
387  Temple::Math::max(
390  )
391  >& indexMapping
392 ) {
393  double chiralDistortion = 0;
394 
395  // C++17:
396  // for(const auto& tetrahedron : ShapeClassFrom::tetrahedra) {
397  for(unsigned i = 0; i < ShapeClassFrom::tetrahedra.size(); ++i) {
398  const auto& tetrahedron = ShapeClassFrom::tetrahedra.at(i);
399 
400  chiralDistortion += Temple::Math::abs(
402  getCoordinates<ShapeClassFrom>(tetrahedron.at(0)),
403  getCoordinates<ShapeClassFrom>(tetrahedron.at(1)),
404  getCoordinates<ShapeClassFrom>(tetrahedron.at(2)),
405  getCoordinates<ShapeClassFrom>(tetrahedron.at(3))
407  getCoordinates<ShapeClassTo>(
408  propagateSymmetryPosition(tetrahedron.at(0), indexMapping)
409  ),
410  getCoordinates<ShapeClassTo>(
411  propagateSymmetryPosition(tetrahedron.at(1), indexMapping)
412  ),
413  getCoordinates<ShapeClassTo>(
414  propagateSymmetryPosition(tetrahedron.at(2), indexMapping)
415  ),
416  getCoordinates<ShapeClassTo>(
417  propagateSymmetryPosition(tetrahedron.at(3), indexMapping)
418  )
419  )
420  );
421  }
422 
423  return chiralDistortion;
424 }
425 
436 template<size_t size>
438  const ArrayType<unsigned, size>& mapping
439 ) {
440  /* Creates the list of indices in the target shape. Why is this necessary?
441  *
442  * E.g. An index mapping from linear to T-shaped. The individual
443  * shape-internal numbering schemes are shown for the shape positions.
444  *
445  * 1 –▶ 0
446  * | |
447  * (_) (_) – 1 (new)
448  * | | Line pos. 0 to
449  * 0 –▶ 2 pos. 2 in Tshaped
450  * | ┌– Line pos. 1 to pos. 0 in Tshaped
451  * | | ┌– This position is new
452  * This mapping is represented as {2, 0, 1}.
453  *
454  * This function writes the indices of original mapping into the target
455  * shape's indexing scheme.
456  *
457  * For this example, this returns {1, 2, 0}:
458  *
459  * 1 (at pos 0 in internal indexing scheme)
460  * |
461  * (_) – 2 (etc.)
462  * |
463  * 0
464  *
465  * The closely related mapping {0, 2, 1} yields target indices {0, 2, 1}.
466  *
467  * Which of these properties are related by target shape rotations?
468  *
469  *
470  * mapping target indices
471  * -----------------------------------
472  * {2, 0, 1} => {1, 2, 0}
473  * ▲ ▲
474  * | |
475  * X | (C2 rotation)
476  * | |
477  * ▼ ▼
478  * {0, 2, 1} => {0, 2, 1}
479  *
480  */
481  ArrayType<unsigned, size> symmetryPositions;
482 
483  for(unsigned i = 0; i < size; ++i) {
484  symmetryPositions.at(
485  mapping.at(i)
486  ) = i;
487  }
488 
489  return symmetryPositions;
490 }
491 
502 template<typename ShapeClass>
503 constexpr unsigned maxRotations() {
504  return Temple::reduce(rotationPeriodicities<ShapeClass>(), 1u, std::multiplies<>());
505 }
506 
507 // Some helper types for use in generateAllRotations
508 template<typename ShapeClass>
509 using IndicesList = ArrayType<unsigned, ShapeClass::size>;
510 
511 using IndexListStorageType = unsigned;
512 
513 template<typename ShapeClass>
514 using RotationsSetType = Temple::DynamicSet<
515  IndicesList<ShapeClass>,
516  maxRotations<ShapeClass>() * 2
517 >;
518 
519 template<typename ShapeClass>
520 using ChainStructuresArrayType = Temple::DynamicArray<
521  IndicesList<ShapeClass>,
522  maxRotations<ShapeClass>() * 2 // factor is entirely arbitrary
523 >;
524 
525 template<typename ShapeClass>
526 using ChainArrayType = Temple::DynamicArray<
527  unsigned,
528  maxRotations<ShapeClass>() * 2 // factor is entirely arbitrary
529 >;
530 
537 template<typename ShapeClass>
538 constexpr auto generateAllRotations(const IndicesList<ShapeClass>& indices) {
540 
541  rotations.insert(indices);
542 
543  ChainStructuresArrayType<ShapeClass> chainStructures;
544  chainStructures.push_back(indices);
545 
546  ChainArrayType<ShapeClass> chain {0u};
547 
548  while(chain.front() < ShapeClass::rotations.size()) {
549 
550  auto generated = applyRotation<ShapeClass>(
551  chainStructures.back(),
552  chain.back()
553  );
554 
555  if(!rotations.contains(generated)) {
556  rotations.insert(generated);
557  chainStructures.push_back(generated);
558  chain.push_back(0);
559  } else {
560  // collapse the chain until we are at an incrementable position (if need be)
561  while(
562  chain.size() > 1
563  && chain.back() == ShapeClass::rotations.size() - 1
564  ) {
565  chain.pop_back();
566  chainStructures.pop_back();
567  }
568 
569  // increment
570  ++chain.back();
571  }
572  }
573 
574  return rotations;
575 }
576 
582  static constexpr size_t maxMappingsSize = 50;
583 
586  maxMappingsSize
587  >;
588 
589  MappingsList mappings;
590  double angularDistortion, chiralDistortion;
591 
592  constexpr MappingsReturnType()
593  : angularDistortion(std::numeric_limits<double>::max()),
594  chiralDistortion(std::numeric_limits<double>::max())
595  {}
596 
597  constexpr MappingsReturnType(
598  MappingsList&& passMappings,
599  double&& passAngularDistortion,
600  double&& passChiralDistortion
601  ) : mappings(passMappings),
602  angularDistortion(passAngularDistortion),
603  chiralDistortion(passChiralDistortion)
604  {}
605 
607  constexpr bool operator == (const MappingsReturnType& other) const {
608  return (
609  mappings == other.mappings
610  && angularDistortion == other.angularDistortion
611  && chiralDistortion == other.chiralDistortion
612  );
613  }
614 
616  constexpr bool operator < (const MappingsReturnType& other) const {
617  return (
618  std::tie(mappings, angularDistortion, chiralDistortion)
619  < std::tie(other.mappings, other.angularDistortion, other.chiralDistortion)
620  );
621  }
622 };
623 
634 template<class ShapeClassFrom, class ShapeClassTo>
635 constexpr auto symmetryTransitionMappings() {
636  static_assert(
637  (
640  ),
641  "This function can handle only cases of equal or increasing shape size"
642  );
643 
644  typename MappingsReturnType::MappingsList bestMappings;
645 
646  double lowestAngleDistortion = 100;
647  double lowestChiralDistortion = 100;
648 
649  auto indexMapping = startingIndexSequence<ShapeClassTo>();
650 
652 
654  floatingPointEqualityTolerance
655  };
656 
657  do {
658  auto mapped = symPosMapping(indexMapping);
659  auto storageVersion = Temple::permutationIndex(mapped);
660 
661  if(!encounteredMappings.test(storageVersion)) {
662  double angularDistortion = calculateAngularDistortion(
663  indexMapping,
667  );
668 
669  double chiralDistortion = calculateChiralDistortion<
670  ShapeClassFrom,
671  ShapeClassTo
672  >(indexMapping);
673 
674  /* Summary of cases:
675  * - If any improvement is made on angular distortion, clear all and add
676  * - If angular distortion is equal but chiral distortion is improved,
677  * clear all and add
678  * - If angular distortion and chiral distortion are equal, just add
679  *
680  * The boolean cases below are, AFAICT, the fewest comparisons.
681  * Feel free to see if you can find some way with fewer.
682  */
683 
684  bool addMapping = (
685  comparator.isLessThan(angularDistortion, lowestAngleDistortion)
686  || (
687  comparator.isEqual(angularDistortion, lowestAngleDistortion)
688  && comparator.isLessOrEqual(chiralDistortion, lowestChiralDistortion)
689  )
690  );
691 
692  bool clearExisting = (
693  addMapping
694  && !(
695  comparator.isEqual(angularDistortion, lowestAngleDistortion)
696  && comparator.isEqual(chiralDistortion, lowestChiralDistortion)
697  )
698  );
699 
700  if(clearExisting) {
701  bestMappings.clear();
702  lowestAngleDistortion = angularDistortion;
703  lowestChiralDistortion = chiralDistortion;
704  }
705 
706  if(addMapping) {
707  bestMappings.insert(indexMapping);
708  }
709 
710  // Add all rotations to the encountered mappings
711  auto allRotations = generateAllRotations<ShapeClassTo>(mapped);
712 
713  for(const auto& rotation : allRotations) {
714  encounteredMappings.set(
715  Temple::permutationIndex(rotation)
716  );
717  }
718  }
719  } while(Temple::inPlaceNextPermutation(indexMapping));
720 
721  return MappingsReturnType(
722  std::move(bestMappings),
723  std::move(lowestAngleDistortion),
724  std::move(lowestChiralDistortion)
725  );
726 }
727 
735 template<class ShapeClassFrom, class ShapeClassTo>
736 constexpr auto ligandLossMappings(const unsigned deletedSymmetryPosition) {
737 
738  static_assert(
740  "Ligand loss pathway calculation must involve shape size decrease"
741  );
742 
743  assert(deletedSymmetryPosition < ShapeClassFrom::size);
744 
745 
746  typename MappingsReturnType::MappingsList bestMappings;
747 
748  double lowestAngleDistortion = 100;
749  double lowestChiralDistortion = 100;
750 
751  // Construct the initial index mapping
753  for(unsigned i = 0; i < deletedSymmetryPosition; ++i) {
754  indexMapping.at(i) = i;
755  }
756  for(unsigned i = deletedSymmetryPosition; i < ShapeClassFrom::size - 1; ++i) {
757  indexMapping.at(i) = i + 1;
758  }
759 
760  /* NOTE: From here the algorithm is identical to symmetryTransitionMappings
761  * save that symmetryTo and symmetryFrom are swapped in all occasions
762  */
764 
766  floatingPointEqualityTolerance
767  };
768 
769  do {
770  auto mapped = symPosMapping(indexMapping);
771  auto storageVersion = Temple::permutationIndex(mapped);
772 
773  if(!encounteredMappings.test(storageVersion)) {
774  double angularDistortion = calculateAngularDistortion(
775  indexMapping,
779  );
780 
781  double chiralDistortion = calculateChiralDistortion<
782  ShapeClassTo,
783  ShapeClassFrom
784  >(indexMapping);
785 
786  bool addMapping = (
787  comparator.isLessThan(angularDistortion, lowestAngleDistortion)
788  || (
789  comparator.isEqual(angularDistortion, lowestAngleDistortion)
790  && comparator.isLessOrEqual(chiralDistortion, lowestChiralDistortion)
791  )
792  );
793 
794  bool clearExisting = (
795  addMapping
796  && !(
797  comparator.isEqual(angularDistortion, lowestAngleDistortion)
798  && comparator.isEqual(chiralDistortion, lowestChiralDistortion)
799  )
800  );
801 
802  if(clearExisting) {
803  bestMappings.clear();
804  lowestAngleDistortion = angularDistortion;
805  lowestChiralDistortion = chiralDistortion;
806  }
807 
808  if(addMapping) {
809  bestMappings.insert(indexMapping);
810  }
811 
812  // Add all rotations to the encountered mappings
813  auto allRotations = generateAllRotations<ShapeClassTo>(indexMapping);
814 
815  for(const auto& rotation : allRotations) {
816  encounteredMappings.set(
817  Temple::permutationIndex(rotation)
818  );
819  }
820  }
821  } while(Temple::inPlaceNextPermutation(indexMapping));
822 
823  return MappingsReturnType(
824  std::move(bestMappings),
825  std::move(lowestAngleDistortion),
826  std::move(lowestChiralDistortion)
827  );
828 }
829 
830 /* Pre-compute all ligand gain situations */
832 template<typename SymmetrySource, typename SymmetryTarget>
833 constexpr
834 std::enable_if_t<
835  (
837  && (
838  SymmetrySource::size == SymmetryTarget::size
840  )
841  ),
845  symmetryTransitionMappings<SymmetrySource, SymmetryTarget>()
846  };
847 }
848 
850 template<typename SymmetrySource, typename SymmetryTarget>
851 constexpr
852 std::enable_if_t<
853  !(
855  && (
858  )
859  ),
863 }
864 
874 template<typename ShapeClass>
875 constexpr unsigned numUnlinkedStereopermutations(
876  const unsigned nIdenticalLigands
877 ) {
878  unsigned count = 1;
879 
880  auto indices = startingIndexSequence<ShapeClass>();
881 
882  for(unsigned i = 0; i < nIdenticalLigands; ++i) {
883  indices.at(i) = 0;
884  }
885 
887 
888  auto initialRotations = generateAllRotations<ShapeClass>(indices);
889 
890  for(const auto& rotation : initialRotations) {
891  rotations.set(Temple::permutationIndex(rotation));
892  }
893 
894  while(Temple::inPlaceNextPermutation(indices)) {
895  if(!rotations.test(Temple::permutationIndex(indices))) {
896  auto allRotations = generateAllRotations<ShapeClass>(indices);
897  for(const auto& rotation : allRotations) {
898  rotations.set(Temple::permutationIndex(rotation));
899  }
900 
901  ++count;
902  }
903  }
904 
905  return count;
906 }
907 
916 template<typename ShapeClass>
917 constexpr bool hasMultipleUnlinkedStereopermutations(const unsigned nIdenticalLigands) {
918  if(nIdenticalLigands == ShapeClass::size) {
919  return false;
920  }
921 
922  auto indices = startingIndexSequence<ShapeClass>();
923 
924  for(unsigned i = 0; i < nIdenticalLigands; ++i) {
925  indices.at(i) = 0;
926  }
927 
929 
930  auto initialRotations = generateAllRotations<ShapeClass>(indices);
931 
932  for(const auto& rotation : initialRotations) {
933  rotations.set(Temple::permutationIndex(rotation));
934  }
935 
936  while(Temple::inPlaceNextPermutation(indices)) {
937  if(!rotations.test(Temple::permutationIndex(indices))) {
938  return true;
939  }
940  }
941 
942  return false;
943 }
944 
945 } // namespace ConstexprProperties
946 } // namespace Shapes
947 } // namespace Molassembler
948 } // namespace Scine
949 
950 #endif
Stubs to work with numeric data.
PURITY_WEAK constexpr bool contains(const T &item) const
Check if the set contains an element.
Definition: DynamicSet.h:61
Fixed-size bitset class.
auto at(Container &&container)
Make functor calling at on arguments.
Definition: Functor.h:58
constexpr double calculateChiralDistortion(const ArrayType< unsigned, Temple::Math::max(ShapeClassFrom::size, ShapeClassTo::size) > &indexMapping)
Calculates the chiral distortion caused by a shape transition.
Definition: Properties.h:384
Data struct to collect the results of calculating the ideal index mappings between pairs of indices...
Definition: Properties.h:581
constexpr auto unpackToFunction()
Definition: TupleType.h:133
constexpr ArrayType< unsigned, ShapeClass::rotations.size()> rotationPeriodicities()
Calculates all multiplicities of a shape group&#39;s rotations.
Definition: Properties.h:235
constexpr auto max(const ContainerType &container)
Composable max function. Returns the smallest value of any container.
Definition: Numeric.h:188
Definition: DynamicArray.h:26
std::tuple< Line, Bent, EquilateralTriangle, VacantTetrahedron, T, Tetrahedron, Square, Seesaw, TrigonalPyramid, SquarePyramid, TrigonalBipyramid, Pentagon, Octahedron, TrigonalPrism, PentagonalPyramid, Hexagon, PentagonalBipyramid, CappedOctahedron, CappedTrigonalPrism, SquareAntiprism, Cube, TrigonalDodecahedron, HexagonalBipyramid, TricappedTrigonalPrism, CappedSquareAntiprism, HeptagonalBipyramid, BicappedSquareAntiprism, EdgeContractedIcosahedron, Icosahedron, Cuboctahedron > allShapeDataTypes
Type collecting all types of the Symmetry classes.
Definition: Data.h:1805
An Option monadic type.
Definition: Optional.h:33
Finds the largest size value of a set of symmetries.
Definition: Properties.h:264
BTree-based std::set-like container (but max size is space allocated)
Centralizes basic shape data in runtime types.
const TetrahedronList & tetrahedra(const Shape shape)
Fetches the list of tetrahedra defined in a shape.
constexpr ArrayType< unsigned, ShapeClass::size > applyRotationImpl(const ArrayType< unsigned, ShapeClass::size > &indices, const unsigned rotationFunctionIndex, std::index_sequence< Indices...>)
Helper to perform applyRotation in constexpr fashion.
Definition: Properties.h:153
constexpr ArrayType< unsigned, size > symPosMapping(const ArrayType< unsigned, size > &mapping)
Transform shape positions through a mapping.
Definition: Properties.h:437
const RotationsList & rotations(const Shape shape)
Fetches a shape&#39;s list of rotations.
constexpr Temple::Vector getCoordinates(const unsigned indexInSymmetry)
Fetches the coordinates of an index in a shape.
Definition: Properties.h:288
constexpr unsigned rotationPeriodicityImpl(const ArrayType< unsigned, ShapeClass::size > &runningIndices, const unsigned count)
Helper to perform rotationPeriodicity in constexpr fashion.
Definition: Properties.h:183
constexpr void set(const std::size_t i)
Sets a specific bit.
Definition: Bitset.h:53
constexpr auto startingIndexSequence()
Generate an integer sequence to use with stereopermutations.
Definition: Properties.h:147
constexpr unsigned numUnlinkedStereopermutations(const unsigned nIdenticalLigands)
Calculate stereopermutations for an unlinked shape.
Definition: Properties.h:875
Functor to find out the minimum angle among all shape class types passed as template arguments...
Definition: Properties.h:114
Temple::Array< T, size > ArrayType
Definition: Properties.h:143
Central symmetry data class definitions.
static constexpr double value()
Minimum angle among all shape classes.
Definition: Properties.h:119
constexpr unsigned rotationPeriodicity()
Determines the multiplicity of a shape group rotation.
Definition: Properties.h:216
constexpr void clear()
Remove all elements of the set.
Definition: DynamicSet.h:78
Tree-based set.
Definition: DynamicSet.h:34
Cache classes.
Constexpr bitset class.
Definition: Bitset.h:26
constexpr bool hasMultipleUnlinkedStereopermutations(const unsigned nIdenticalLigands)
Calculates whether a shape has multiple stereopermutations.
Definition: Properties.h:917
constexpr ArrayType< unsigned, ShapeClass::rotations.size()> rotationPeriodicitiesImpl(std::index_sequence< Inds...>)
Helper function to calculate all rotation periodicities.
Definition: Properties.h:229
constexpr T reduce(const ArrayType< T, size > &array, T init, BinaryFunction &&reduction)
Reduce an array-like container with a binary function.
Definition: Containers.h:88
constexpr std::enable_if_t< (SymmetryTarget::size<=7 &&(SymmetrySource::size==SymmetryTarget::size||SymmetrySource::size+1==SymmetryTarget::size)), Temple::Optional< MappingsReturnType >> calculateMapping()
If symmetries are adjacent, calculate their shape transition mapping.
Definition: Properties.h:843
unsigned size(const Shape shape)
Fetch the number of vertices of a shape.
constexpr double getTetrahedronVolume(const Temple::Vector &i, const Temple::Vector &j, const Temple::Vector &k, const Temple::Vector &l)
Calculates the volume of a tetrahedron spanned by four positions.
Definition: Properties.h:301
Metafunction calculating the smallest and largest angle that exist in a shape.
Definition: Properties.h:81
AngleFunction angleFunction(const Shape shape)
Gets a shape&#39;s angle function.
constexpr double calculateSmallestAngle()
Calculates the minimum angle returned in a shape class.
Definition: Properties.h:59
constexpr ArrayType< unsigned, ShapeClass::size > applyRotation(const ArrayType< unsigned, ShapeClass::size > &indices, const unsigned rotationFunctionIndex)
Applies a shape group rotation to an array of indices.
Definition: Properties.h:170
constexpr bool arraysEqual(const ArrayType< T, size > &a, const ArrayType< T, size > &b)
Array-like container lexicographic equality comparaotr.
Definition: Containers.h:280
Constexpr three-dimensional vector math class.
Definition: Vector.h:25
constexpr unsigned ORIGIN_PLACEHOLDER
A placeholder value for constexpr tetrahedra specification of origin.
Definition: Data.h:24
constexpr bool test(const std::size_t i) const
Test the value at a particular bit.
Definition: Bitset.h:90
constexpr double calculateAngularDistortion(const ArrayType< unsigned, size > &indexMapping, const size_t sourceSymmetrySize, const AngleFunctionPtr sourceAngleFunction, const AngleFunctionPtr targetAngleFunction)
Calculates angular distortion caused by a shape transition mapping.
Definition: Properties.h:326
static constexpr std::pair< double, double > value()
Smallest and largest angles of the ShapeClass.
Definition: Properties.h:86
Coordinates coordinates(const Shape shape)
Fetch a shape&#39;s idealized coordiantes.
constexpr auto ligandLossMappings(const unsigned deletedSymmetryPosition)
Find index mappings for ligand loss situations.
Definition: Properties.h:736
constexpr auto symmetryTransitionMappings()
Calculates ideal index mappings for +1, 0 size transitions.
Definition: Properties.h:635
constexpr double smallestAngle[[gnu::unused]]
The smallest angle between ligands in all symmetries.
Definition: PropertyCaching.h:46
constexpr unsigned maxShapeSize
The largest shape size defined in the library.
Definition: Properties.h:275
Calculate the multiplicities of all rotations of a shape.
Definition: Properties.h:253
constexpr unsigned propagateSymmetryPosition(const unsigned symmetryPosition, const ArrayType< unsigned, size > &indexMapping)
Propagates shape positions trhough an index mapping.
Definition: Properties.h:361
constexpr void insert(const T &item)
Insertion an element into the set.
Definition: DynamicSet.h:69
constexpr unsigned maxRotations()
Definition: Properties.h:503
std::size_t permutationIndex(const Container &container)
Calculate the index of permutation of elements in a container.
Definition: Permutations.h:25
Helpers for comparing floating point values.
constexpr auto generateAllRotations(const IndicesList< ShapeClass > &indices)
Generates all rotations of a sequence of indices within a shape group.
Definition: Properties.h:538