Molassembler  1.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ImplicitBoundsGraph.h
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_DISTANCE_GEOMETRY_IMPLICIT_BOUNDS_GRAPH_H
13 #define INCLUDE_DISTANCE_GEOMETRY_IMPLICIT_BOUNDS_GRAPH_H
14 
15 // #define MOLASSEMBLER_IMPLICIT_GRAPH_USE_SPECIALIZED_GOR1_ALGORITHM
16 
17 #include "boost/property_map/property_map.hpp"
18 #include "Eigen/Core"
20 
23 
24 #include <array>
25 #include <map>
26 #include <tuple>
27 
28 namespace Scine {
29 namespace Molassembler {
30 
31 namespace Random {
32 class Engine;
33 } // namespace Random
34 
35 namespace outcome = OUTCOME_V2_NAMESPACE;
36 
37 // Forward-declare PrivateGraph
38 class PrivateGraph;
39 
40 namespace DistanceGeometry {
41 
42 // Forward-declarations
43 class DistanceBoundsMatrix;
44 
146 public:
147  using VertexDescriptor = unsigned long;
148  using EdgeDescriptor = std::pair<VertexDescriptor, VertexDescriptor>;
149 
150  /* To outer indexing */
151  [[gnu::const]] inline static VertexDescriptor left(const VertexDescriptor a) noexcept {
152  return 2 * a;
153  }
154 
155  [[gnu::const]] inline static VertexDescriptor right(const VertexDescriptor a) noexcept {
156  return 2 * a + 1;
157  }
158 
159  [[gnu::const]] inline static VertexDescriptor internal(const VertexDescriptor i) noexcept {
160  // Integer division rounds down, which is perfect
161  return i / 2;
162  }
163 
164 private:
167 
169  std::array<Utils::ElementType, 2> heaviestAtoms_;
170 
172  Eigen::MatrixXd distances_;
173 
174  static void explainContradictionPaths_(
175  VertexDescriptor a,
176  VertexDescriptor b,
177  const std::vector<VertexDescriptor>& predecessors,
178  const std::vector<double>& distances
179  );
180 
181 public:
182  using BoundsMatrix = Eigen::MatrixXd;
183 
185  const PrivateGraph& inner,
186  BoundsMatrix bounds
187  );
188 
189  /* Information */
196  VertexDescriptor num_vertices() const;
197 
204  VertexDescriptor num_edges() const;
205 
215  std::pair<EdgeDescriptor, bool> edge(VertexDescriptor i, VertexDescriptor j) const;
216 
221  bool hasExplicit(const EdgeDescriptor& edge) const;
222 
223  /* To inner indexing */
228  [[gnu::const]] inline static bool isLeft(const VertexDescriptor i) noexcept {
229  return i % 2 == 0;
230  }
231 
232  [[gnu::const]] inline static bool sameSide(const VertexDescriptor i, const VertexDescriptor j) noexcept {
233  return i % 2 == j % 2;
234  }
235 
244  outcome::result<Eigen::MatrixXd> makeDistanceBounds() const noexcept;
245 
261  outcome::result<Eigen::MatrixXd> makeDistanceMatrix(Random::Engine& engine) noexcept;
262 
264  outcome::result<Eigen::MatrixXd> makeDistanceMatrix(Random::Engine& engine, Partiality partiality) noexcept;
265 
270  inline VertexDescriptor source(const EdgeDescriptor& e) const {
271  return e.first;
272  }
273 
278  inline VertexDescriptor target(const EdgeDescriptor& e) const {
279  return e.second;
280  }
281 
286  inline const Eigen::MatrixXd& getMatrix() const {
287  return distances_;
288  }
289 
294  VertexDescriptor out_degree(VertexDescriptor i) const;
295 
296  /* These are all O(1) */
297  double& lowerBound(VertexDescriptor a, VertexDescriptor b);
298  double& upperBound(VertexDescriptor a, VertexDescriptor b);
299 
300  double lowerBound(VertexDescriptor a, VertexDescriptor b) const;
301  double upperBound(VertexDescriptor a, VertexDescriptor b) const;
302 
307  double maximalImplicitLowerBound(VertexDescriptor i) const;
308 
310  struct EdgeWeightMap : public boost::put_get_helper<double, EdgeWeightMap> {
311  using value_type = double;
312  using reference = double;
313  using key_type = EdgeDescriptor;
314 
315  const ImplicitBoundsGraph* basePtr_;
316 
317  EdgeWeightMap(const ImplicitBoundsGraph& base);
318  double operator [] (const EdgeDescriptor& e) const;
319  double operator () (const EdgeDescriptor& e) const;
320  };
321 
324 
326  struct VertexIndexMap : public boost::put_get_helper<VertexDescriptor, VertexIndexMap> {
327  using value_type = VertexDescriptor;
328  using key_type = VertexDescriptor;
329  using reference = VertexDescriptor;
330 
331  inline VertexDescriptor operator [] (const VertexDescriptor v) const { return v; }
332  inline VertexDescriptor operator () (const VertexDescriptor v) const { return v; }
333  };
334 
337  VertexDescriptor index = 0;
338 
339  public:
340  using iterator_category = std::random_access_iterator_tag;
341  using value_type = VertexDescriptor;
342  using difference_type = int;
343  using pointer = VertexDescriptor*;
344  using reference = const VertexDescriptor&;
345 
346  vertex_iterator();
347  vertex_iterator(VertexDescriptor i);
348  vertex_iterator(const vertex_iterator& other);
349  vertex_iterator(vertex_iterator&& other) noexcept;
350  vertex_iterator& operator = (const vertex_iterator& other);
351  vertex_iterator& operator = (vertex_iterator&& other) noexcept;
352 
353  bool operator == (const vertex_iterator& other) const;
354 
355  bool operator != (const vertex_iterator& other) const;
356 
357  vertex_iterator& operator ++ ();
358 
359  vertex_iterator operator ++ (int);
360 
361  vertex_iterator& operator -- ();
362 
363  vertex_iterator operator -- (int);
364 
365  vertex_iterator& operator + (unsigned i);
366 
367  vertex_iterator& operator - (unsigned i);
368 
369  VertexDescriptor operator * () const;
370 
371  int operator - (const vertex_iterator& other) const;
372  };
373 
375  vertex_iterator vbegin () const;
376 
378  vertex_iterator vend() const;
379 
382  const ImplicitBoundsGraph* basePtr_;
383 
384  VertexDescriptor i_, b_;
385  bool crossGroup_;
386 
387  void increment_();
388 
389  public:
390  using iterator_category = std::forward_iterator_tag;
391  using value_type = EdgeDescriptor;
392  using difference_type = int;
393  using pointer = EdgeDescriptor*;
394  using reference = const EdgeDescriptor&;
395 
396  edge_iterator();
398  const ImplicitBoundsGraph& base,
399  VertexDescriptor i
400  );
401  edge_iterator(const edge_iterator& other);
402  edge_iterator(edge_iterator&& other) noexcept;
403  edge_iterator& operator = (const edge_iterator& other);
404  edge_iterator& operator = (edge_iterator&& other) noexcept;
405 
406  edge_iterator& operator ++ ();
407 
408  edge_iterator operator ++ (int);
409 
410  bool operator == (const edge_iterator& other) const;
411 
412  bool operator != (const edge_iterator& other) const;
413 
414  std::string state() const;
415 
416  EdgeDescriptor operator * () const;
417 
418  double weight() const;
419  VertexDescriptor target() const;
420  };
421 
423  edge_iterator ebegin() const;
424 
426  edge_iterator eend() const;
427 
429  edge_iterator obegin(VertexDescriptor i) const;
430 
432  edge_iterator oend(VertexDescriptor i) const;
433 
436  const ImplicitBoundsGraph* basePtr_;
437  VertexDescriptor i_;
438  VertexDescriptor b_;
439  bool isLeft_;
440 
441  public:
442  using iterator_category = std::forward_iterator_tag;
443  using value_type = EdgeDescriptor;
444  using difference_type = int;
445  using pointer = EdgeDescriptor*;
446  using reference = const EdgeDescriptor&;
447 
448  // Default constructor
450  // Constructor for the begin iterator
451  in_group_edge_iterator(const ImplicitBoundsGraph& base, VertexDescriptor i);
452  // Constructor for the end iterator
454  const ImplicitBoundsGraph& base,
455  VertexDescriptor i,
456  bool /* tag */
457  );
460  in_group_edge_iterator& operator = (in_group_edge_iterator&& other) noexcept;
461  in_group_edge_iterator& operator = (const in_group_edge_iterator& other);
462 
463  inline in_group_edge_iterator& operator ++ () {
464  /* Find the next position in the matrix with information
465  * The fastest way to check if there is information is to just access
466  * either the lower or upper bound, and convert the double there to
467  * boolean. That boolean is true only if the double is != 0.
468  */
469  ++b_;
470  while(
471  b_ < static_cast<VertexDescriptor>(basePtr_->distances_.outerSize())
472  && (basePtr_->distances_(internal(i_), b_) == 0.0)
473  ) {
474  ++b_;
475  }
476  return *this;
477  }
478 
479  inline in_group_edge_iterator operator ++ (int) {
480  auto copy = *this;
481  ++(*this);
482  return copy;
483  }
484 
485  inline bool operator == (const in_group_edge_iterator& other) {
486  return (
487  isLeft_ == other.isLeft_
488  && i_ == other.i_
489  && b_ == other.b_
490  && basePtr_ == other.basePtr_
491  );
492  }
493  inline bool operator != (const in_group_edge_iterator& other) {
494  return !(*this == other);
495  }
496 
497  inline EdgeDescriptor operator *() const {
498  return {i_, target()};
499  }
500 
501  inline VertexDescriptor target() const {
502  if(isLeft_) {
503  return left(b_);
504  }
505 
506  return right(b_);
507  }
508 
509  inline double weight() const {
510  return basePtr_->upperBound(internal(i_), b_);
511  }
512  };
513 
514  inline in_group_edge_iterator in_group_edges_begin(const VertexDescriptor i) const {
515  return {*this, i};
516  }
517 
518  inline in_group_edge_iterator in_group_edges_end(const VertexDescriptor i) const {
519  return {*this, i, true};
520  }
521 };
522 
523 } // namespace DistanceGeometry
524 } // namespace Molassembler
525 } // namespace Scine
526 
527 #endif
VertexDescriptor num_edges() const
Returns the number of edges currently simulated by the graph.
VertexDescriptor num_vertices() const
Returns the number of vertices simulated by the graph, which is 2N.
A helper struct to turn vertex descriptors into numeric indices.
Definition: ImplicitBoundsGraph.h:326
VertexDescriptor out_degree(VertexDescriptor i) const
Returns the number of out-edges for a particular vertex.
std::pair< EdgeDescriptor, bool > edge(VertexDescriptor i, VertexDescriptor j) const
Fetches an edge descriptor for a speculative edge from i to j.
const Eigen::MatrixXd & getMatrix() const
Allows const-ref access to the underlying matrix for debug purposes.
Definition: ImplicitBoundsGraph.h:286
Simulates a graph from which triangle inequality bounds can be calculated by shortest-paths.
Definition: ImplicitBoundsGraph.h:145
outcome::result< Eigen::MatrixXd > makeDistanceMatrix(Random::Engine &engine) noexcept
Generates a distance matrix by randomly fixing distances within triangle inequality bounds...
edge_iterator eend() const
Returns an end edge iterator.
vertex_iterator vbegin() const
Returns a begin-iterator for vertices.
VertexDescriptor target(const EdgeDescriptor &e) const
Returns the target vertex from an edge descriptor.
Definition: ImplicitBoundsGraph.h:278
A helper struct permitting read-access to an edge weight via an edge descriptor.
Definition: ImplicitBoundsGraph.h:310
Data struct for storing a numeric interval.
Library internal graph class wrapping BGL types.
Definition: PrivateGraph.h:24
VertexDescriptor source(const EdgeDescriptor &e) const
Returns the source vertex from an edge descriptor.
Definition: ImplicitBoundsGraph.h:270
An iterator to enumerate all edges in a graph.
Definition: ImplicitBoundsGraph.h:381
edge_iterator oend(VertexDescriptor i) const
Returns an end edge iterator for the out-edges of a specific vertex.
bool hasExplicit(const EdgeDescriptor &edge) const
Checks if there is explicit information present for a left-to-right edge.
edge_iterator obegin(VertexDescriptor i) const
Returns a begin edge iterator for the out-edges of a specific vertex.
std::array< Utils::ElementType, 2 > heaviestAtoms_
Stores the two heaviest element types.
Definition: ImplicitBoundsGraph.h:169
vertex_iterator vend() const
Returns an end-iterator for vertices.
Eigen::MatrixXd distances_
Dense adjacency matrix for O(1) access to fixed distances.
Definition: ImplicitBoundsGraph.h:172
static bool isLeft(const VertexDescriptor i) noexcept
Check if a vertex descriptor is part of the left subgraph.
Definition: ImplicitBoundsGraph.h:228
A random access iterator through all vertex descriptors of the graph.
Definition: ImplicitBoundsGraph.h:336
An iterator to enumerate only edges to the same part of the graph from specific vertices.
Definition: ImplicitBoundsGraph.h:435
EdgeWeightMap getEdgeWeightPropertyMap() const
Returns an instance of EdgeWeightMap.
const PrivateGraph * innerGraphPtr_
Pointer to molecule from which the bounds come from.
Definition: ImplicitBoundsGraph.h:166
edge_iterator ebegin() const
Returns a begin edge iterator.
Interface for the generation of new conformations of Molecules.
Partiality
Limit triangle inequality bounds smoothing to a subset of all atoms.
Definition: Conformers.h:44
outcome::result< Eigen::MatrixXd > makeDistanceBounds() const noexcept
Generates a bare distance bounds matrix by repeated shortest-paths calculations.
double maximalImplicitLowerBound(VertexDescriptor i) const
Returns the length of the maximal implicit lower bound outgoing from a left vertex.