Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DoubleLazyInteractionGraph.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/pack/interaction_graph/DoubleLazyInteractionGraph.hh
11 /// @brief Interaction graph that computes each rotamer pair energy at most once
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 #ifndef INCLUDED_core_pack_interaction_graph_DoubleLazyInteractionGraph_hh
15 #define INCLUDED_core_pack_interaction_graph_DoubleLazyInteractionGraph_hh
16 
17 // Unit headers
19 
20 // Package Headers
22 // AUTO-REMOVED #include <core/pack/interaction_graph/AminoAcidNeighborSparseMatrix.hh>
23 
25 
26 // Utility headers
27 #include <utility/in_place_list.fwd.hh>
28 #include <utility/vector0.hh>
29 
30 // ObjexxFCL headers
31 #include <ObjexxFCL/FArray1D.hh>
32 
33 #include <utility/vector1.hh>
34 
35 
36 // The double-lazy interaction graph is lazy both in its computation of
37 // rotamer pair energies and in its allocation of memory for rotamer
38 // pair energies. Each rotamer pair energy is computed at most once.
39 // AA neighbor submatrices are only allocated
40 // when they are needed. This interaction graph is particularly well
41 // suited for multistate design where single aa-submatrices are used
42 // at a time.
43 
44 namespace core {
45 namespace pack {
46 namespace interaction_graph {
47 
49 {
50 public:
52  InteractionGraphBase * owner,
53  int node_id,
54  int num_states
55  );
56 
57  virtual ~DoubleLazyNode();
58 
59  //virtual methods inherited from NodeBase
60  virtual void prepare_for_simulated_annealing();
61  virtual void print() const;
62  virtual bool state_unassigned() const { return current_state_ == 0;}
64 
65  void assign_zero_state();
66  void assign_state(int new_state);
67  void partial_assign_state( int new_state );
69 
70  inline
71  int get_current_state() const { return current_state_; }
72 
73  inline
75  { return curr_state_one_body_energy_; }
76 
77  inline
79  (
80  int alternate_state,
81  core::PackerEnergy & prev_node_energy
82  );
83 
85  core::PackerEnergy compute_pair_energy_for_current_state( int edge_making_energy_request );
86 
87  inline
89  int edge_to_altered_neighbor,
90  core::PackerEnergy new_edge_energy,
91  int other_node_new_state,
92  SparseMatrixIndex const & other_node_new_state_sparse_info
93  );
94 
95  void
97  int edge_to_altered_neighbor,
98  int other_node_new_,
99  SparseMatrixIndex const & other_node_new_state_sparse_info
100  );
101 
102  inline
103  SparseMatrixIndex const &
105 
106  void print_internal_energies() const;
107 
109 
110  virtual unsigned int count_static_memory() const;
111  virtual unsigned int count_dynamic_memory() const;
112  //unsigned int potential_edge_memory_use() const;
113 
114  virtual
115  int aatype_for_state( int state ) const;
116 
117 protected:
118 
119  /*inline
120  rotamer_trie const &
121  get_current_rotamer()
122  {
123  return get_rotamer( current_state_ );
124  }*/
125 
126  /*
127  inline
128  core::PackerEnergy &
129  get_curr_rotamer_actcoords();
130  */
131 
132  //Hooks for SASANode< V, E, G > class
135  void set_alternate_state( int alt ) { alternate_state_ = alt; }
136  int get_alternate_state() const { return alternate_state_; }
137  void calc_deltaEpd( int alternate_state );
139  {
141  }
142 
143 
144 private:
145 
146  //void
147  //set_alt_aa_offsets_from_edge(int edge_index, FArray2D_int const & offsets);
148 
150 
151  /// Pointer Downcasts
152  inline DoubleLazyEdge const * get_incident_dlazy_edge( int index ) const;
153  inline DoubleLazyEdge * get_incident_dlazy_edge( int index ) ;
154  inline DoubleLazyNode const * get_adjacent_dlazy_node( int index ) const;
155  inline DoubleLazyNode * get_adjacent_dlazy_node( int index ) ;
156  inline DoubleLazyInteractionGraph const * get_dlazy_ig_owner() const;
158 
159 private:
160  // DATA
161 
162  //FArray3D_int aa_offsets_for_edges_;
163  //FArray2D_int num_states_for_aa_type_for_higher_indexed_neighbor_;
164  //std::vector< FArray1Da< core::PackerEnergy > > edge_matrix_ptrs_;
165 
166  std::vector< int > neighbors_curr_state_;
167  std::vector< SparseMatrixIndex > neighbors_curr_state_sparse_info_;
168 
173  std::vector< core::PackerEnergy > curr_state_two_body_energies_;
174 
179  std::vector< core::PackerEnergy > alternate_state_two_body_energies_;
180 
183 
184  //no default constructor, uncopyable
185  DoubleLazyNode();
186  DoubleLazyNode( DoubleLazyNode const & );
188 
189 };
190 
192 {
193 public:
195  InteractionGraphBase* owner,
196  int first_node_ind,
197  int second_node_ind
198  );
199 
200  virtual ~DoubleLazyEdge();
201 
202  virtual
203  void
205  FArray2_bool const &
206  );
207 
208  virtual
209  void force_aa_neighbors( int node1aa, int node2aa);
210 
211  virtual
212  void force_all_aa_neighbors();
213 
214  virtual
215  bool
217  int node1aa,
218  int node2aa
219  ) const;
220 
221  virtual core::PackerEnergy get_two_body_energy( int const node1state, int const node2state) const;
222 
225  int const node1state,
226  int const node2state,
227  SparseMatrixIndex const & node1info,
228  SparseMatrixIndex const & node2info
229  ) const;
230 
231  //virtual methods inherited from EdgeBase
232  virtual void declare_energies_final();
233  virtual void prepare_for_simulated_annealing();
234 
236 
238  int node_ind,
239  int new_state,
240  SparseMatrixIndex const & new_state_sparse_info,
241  core::PackerEnergy & new_energy
242  );
243  void acknowledge_state_zeroed( int node_ind );
244 
246  int node_ind,
247  int new_state,
248  SparseMatrixIndex const & new_state_sparse_info
249  );
251 
252  /* inline
253  core::PackerEnergy get_alternate_state_energy_first_node(
254  int first_node_alt_state,
255  int second_node_orig_state,
256  SparseMatrixIndex const & first_node_alt_state_sparse_info,
257  SparseMatrixIndex const & second_node_orig_state_sparse_info
258  ); */
259 
260  /* inline
261  core::PackerEnergy get_alternate_state_energy_second_node(
262  int first_node_orig_state,
263  int second_node_alt_state,
264  SparseMatrixIndex const & first_node_orig_state_sparse_info,
265  SparseMatrixIndex const & second_node_alternate_state_sparse_info
266  ); */
267 
268  inline
270  int substituted_node_index,
271  core::PackerEnergy const curr_state_energy,
272  int nodes_new_state,
273  SparseMatrixIndex const & nodes_new_state_sparse_info
274  );
275 
276  void set_edge_weight( Real weight );
277 
278  //core::PackerEnergy & get_edge_table_ptr();
279  int get_two_body_table_size() const;
280 
281  void print_current_energy() const;
282 
283  bool build_sc_only_rotamer() { return true;}
284 
285  //FArray2D_int const & get_offsets_for_aatypes( );
286  //utility::vector1< int > const & get_second_node_num_states_per_aa();
287 
288  ObjexxFCL::FArray2D< core::PackerEnergy >
290  int node1aa,
291  int node2aa
292  ) const;
293 
294  static core::PackerEnergy const NOT_YET_COMPUTED_ENERGY; //an energy lower than any RPE could ever be
295 
296  virtual unsigned int count_static_memory() const;
297  virtual unsigned int count_dynamic_memory() const;
298 
299  unsigned int
301 
302  unsigned int
304 
305  /// @brief For use by the DoubleLazyInteractionGraph only;
306  /// sets the edge index for this edge -- this is an arbitrary
307  /// index, but is used to so that the DLIG can communicate back
308  /// and forth with this edge.
309  void
311  int index
312  );
313 
314  /// @brief For use by the DoubleLazyInteractionGraph only; if the DLIG is in "memory conservation"
315  /// mode, then it may request that its edges drop certain amino acid submatrices which have not been activated
316  /// for a "long time." This function will cause an amino-acid submatrix to be dropped, and will return
317  /// the number of bytes that have been freed in the process. "const" but accesses mutable data
318  int
320  int submat_ind
321  ) const;
322 
323 protected:
324 
325  //Hooks for SASAEdge< V, E, G > class
328  bool pd_edge_table_all_zeros() const { return false;}
329 
330 private:
331 
332  void
334  int node1aa,
335  int node2aa
336  ) const;
337 
340  SparseMatrixIndex node1info,
341  SparseMatrixIndex node2info
342  ) const;
343 
344  void
346  SparseMatrixIndex node1info,
347  SparseMatrixIndex node2info,
348  core::PackerEnergy setting
349  ) const;
350 
352  int nodes_states[ 2 ],
353  SparseMatrixIndex sparse_matrix_indices[ 2 ]
354  );
355 
356  inline DoubleLazyNode const * get_dlazy_node( int index ) const;
357  inline DoubleLazyNode * get_dlazy_node( int index );
358  inline DoubleLazyInteractionGraph const * get_dlazy_ig_owner() const;
360 
361  void
362  wipe_two_body_energies_for_node_state( int node, int state );
363 
364  int
365  submatrix_index( int nod1aa, int node2aa ) const;
366 
367  int
368  submatrix_size( int node1aa, int node2aa ) const;
369 
370  std::pair< int, int >
371  aa_indices_from_submatrix_index( int submat_ind ) const;
372 
373 private:
374  /// record which amino acid pairs are neighbors
375  ObjexxFCL::FArray2D< unsigned char > sparse_aa_neighbors_;
376  /// Allocate the amino-acid submatrices of the two-body energy table only as needed.
377  /// In a more advanced version of this graph, these submatrices would be deleted again
378  /// (and possibly re-instantiated!) after a long time had passed since they were last useful.
379  mutable ObjexxFCL::FArray2D< ObjexxFCL::FArray2D< core::PackerEnergy > * > two_body_energies_;
383 
384  // The double-lazy interaction graph keeps a vector of edges and assigns an
385  // index to each edge. The DLIG and its edges communicate to each other based
386  // on this (arbitrary) indexing. The index is assigned in
387  // prepare_for_simulated_annealing
389 
390  //no default constructor, uncopyable
391  DoubleLazyEdge();
392  DoubleLazyEdge( DoubleLazyEdge const & );
394 
395 };
396 
397 /// @brief The double lazy interaction graph is primarily useful for multistate design
398 /// where one is interested in knowing at particular edge, all of the rotamer pair energies
399 /// for a particular amino acid assignment.
400 /// The double lazy interaction graph is lazy in two ways: first, in delaying the computation
401 /// of rotamer pair energies until they are needed, and second, in delaying the allocation of
402 /// memory for rotamer pair energies until that memory is needed.
403 /// The DLIG will do one of two things once it allocates space for a block of rotamer pairs:
404 /// 1) In its standard operating behavior, it will leave that space allocated until
405 /// the graph is destroyed, which means that the energies it stores in that block will never
406 /// be computed more than once; or
407 /// 2) In its alternate operating behavior, the LMIG will deallocate some of those blocks
408 /// to make sure that it never uses more than some maximum amount of memory on RPEs.
410 {
411 public:
413 
414 public:
415  DoubleLazyInteractionGraph( int numNodes );
416  virtual ~DoubleLazyInteractionGraph();
417  virtual void initialize( rotamer_set::RotamerSetsBase const & rot_sets );
418 
419  //virtual methods inherited from InteractionGraphBase
420  virtual void prepare_for_simulated_annealing();
421  virtual void blanket_assign_state_0();
422  virtual core::PackerEnergy set_state_for_node(int node_ind, int new_state);
423  virtual core::PackerEnergy set_network_state( FArray1_int & node_states);
424  virtual void consider_substitution(
425  int node_ind,
426  int new_state,
427  core::PackerEnergy & delta_energy,
428  core::PackerEnergy & prev_energy_for_node
429  );
432  virtual int get_edge_memory_usage() const;
433  virtual void print_current_state_assignment() const;
434  virtual void set_errorfull_deltaE_threshold( core::PackerEnergy deltaE );
435  virtual core::PackerEnergy get_energy_sum_for_vertex_group( int group_id );
436 
437  /// @brief Override the FixedBBInteractionGraph class's implementation of this function
438  /// to return 'true'.
439  virtual
440  bool
442 
443  virtual
445  int node_ind,
446  int node_state
447  ) const;
448 
449  virtual
450  ObjexxFCL::FArray2D< core::PackerEnergy >
452  int node1,
453  int node2,
454  int node1aa,
455  int node2aa
456  ) const;
457 
458  virtual unsigned int count_static_memory() const;
459  virtual unsigned int count_dynamic_memory() const;
460 
461  void set_memory_max_for_rpes( int setting );
462 
463  /// @brief For use only from the DoubleLazyEdge; the DLE will report
464  /// to the DLIG after it adds a submatrix of rotamer pair energies
465  /// (that is, all the RPEs for a particular pair of amino acids)
466  /// that it has done so; the DLIG monitors the access and the memory
467  /// usage of the various submatrices in the graph, and may, during
468  /// this function call, request that various edges (possibly the one
469  /// invoking this function!) drop some of their submatrices.
471  int edge_index,
472  int submatrix_index,
473  int submatrix_size // in bytes
474  ) const;
475 
476  /// @brief For use only from the DoubleLazyEdge; the DLE will
477  /// report to the DLIG after it a rotamer pair energy submatrix
478  /// has been read from. The DLIG keeps track of how recently each
479  /// submatrix has been accessed to ensure that, when it does ask
480  /// an edge to drop a submatrix, the submatrix being dropped
481  /// is the one that was accessed most distantly in the past.
483  int edge_index,
484  int submatrix_index
485  ) const;
486 
487 
488 protected:
489 
490  virtual NodeBase* create_new_node( int node_index, int num_states);
491  virtual EdgeBase* create_new_edge( int index1, int index2);
492 
493  //Hooks for SASAInterationGraph< V, E, G >
496 
497  inline
498  DoubleLazyNode const * get_dlazy_node(int index) const
499  {
500  return static_cast< DoubleLazyNode const * > (get_node( index ));
501  }
502 
503  inline
505  {
506  return static_cast< DoubleLazyNode * > (get_node( index ));
507  }
508 
509  inline
510  DoubleLazyEdge const * get_dlazy_edge( int node1, int node2 ) const
511  {
512  return static_cast< DoubleLazyEdge const * > (find_edge( node1, node2 ));
513  }
514 
515  inline
516  DoubleLazyEdge * get_dlazy_edge( int node1, int node2 )
517  {
518  return static_cast< DoubleLazyEdge * > (find_edge( node1, node2 ));
519  }
520 
521 private:
522  int sqr_num_aa_types_; // == num_aa_types_ * num_aa_types_;
527 
528  static const int COMMIT_LIMIT_BETWEEN_UPDATES = 1024; // 2^10
529 
530  // the maximum amount of memory that should be dedicated
531  // toward rotamer pair energies within the graph.
534 
535  /// initialized in prepare_for_simulated_annealing();
538 
539  //no default constructor, uncopyable
543 
544 };
545 
546 inline
548 {
549  return static_cast< DoubleLazyEdge const * > (get_incident_edge( index ));
550 }
551 
552 inline
554 {
555  return static_cast< DoubleLazyEdge * > (get_incident_edge( index ));
556 }
557 
558 inline
560 {
561  return static_cast< DoubleLazyNode const * > (get_adjacent_node( index ));
562 }
563 
564 inline
566 {
567  return static_cast< DoubleLazyNode * > (get_adjacent_node( index ));
568 }
569 
570 inline
572 {
573  return static_cast< DoubleLazyInteractionGraph const * > (get_owner());
574 }
575 
576 inline
578 {
579  return static_cast< DoubleLazyInteractionGraph * > (get_owner());
580 }
581 
582 
583 inline
585 {
586  return static_cast< DoubleLazyNode const * > (get_node( index ));
587 }
588 
589 inline
591 {
592  return static_cast< DoubleLazyNode * > (get_node( index ));
593 }
594 
595 inline
597 {
598  return static_cast< DoubleLazyInteractionGraph const * > (get_owner());
599 }
600 
601 inline
603 {
604  return static_cast< DoubleLazyInteractionGraph * > (get_owner());
605 }
606 
607 inline
608 void
610  int substituted_node_index,
611  core::PackerEnergy const curr_state_energy,
612  int nodes_new_state,
613  SparseMatrixIndex const & nodes_new_state_sparse_info
614 )
615 {
616  int node_substituted = substituted_node_index == get_node_index(0) ? 0 : 1;
617  int node_not_substituted = ! node_substituted;
618 
619  curr_state_energy_ = curr_state_energy;
620 
622  get_edges_position_in_nodes_edge_vector( node_not_substituted ),
624  nodes_new_state,
625  nodes_new_state_sparse_info
626  );
627 
628  return;
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// @begin DoubleLazyNode::project_deltaE_for_substitution
633 ///
634 /// @brief
635 ///
636 /// @detailed
637 ///
638 /// @param
639 ///
640 /// @global_read
641 ///
642 /// @global_write
643 ///
644 /// @remarks
645 ///
646 /// @references
647 ///
648 /// @authors apl
649 ///
650 /// @last_modified
651 ////////////////////////////////////////////////////////////////////////////////
652 inline
655 (
656  int alternate_state,
657  core::PackerEnergy & prev_node_energy
658 )
659 {
660  alternate_state_is_being_considered_ = true;
661  //procrastinated_ = false;
662  //std::cout << "proj_deltaE: node - " << get_node_index()
663  // << " alt state " << alternate_state << "...";
664 
665  alternate_state_ = alternate_state;
666 
667  alt_state_sparse_mat_info_ = get_sparse_mat_info_for_state( alternate_state );
668  alternate_state_one_body_energy_ = get_one_body_energy( alternate_state );
669  alternate_state_total_energy_ = alternate_state_one_body_energy_;
670  prev_node_energy = curr_state_total_energy_;
671 
672  //int aa_neighb_linear_index_offset = aa_offsets_for_edges_.
673  // index(1, 1, alt_state_sparse_mat_info_.get_aa_type() ) - 1;
674 
675  //int alt_state_num_states_per_aa_type =
676  // get_num_states_for_aa_type( alt_state_sparse_mat_info_.get_aa_type() );
677  //int alt_state_for_aa_type_minus_1 =
678  // alt_state_sparse_mat_info_.get_state_ind_for_this_aa_type() - 1;
679  //int nstates_offset =
680  // num_states_for_aa_type_for_higher_indexed_neighbor_.index(1,1) - 1;
681 
682  for ( int ii = 1; ii <= get_num_edges_to_smaller_indexed_nodes(); ++ii ) {
683 
684  alternate_state_two_body_energies_[ ii ] = get_incident_dlazy_edge(ii)->
685  get_two_body_energy_smi(
686  neighbors_curr_state_[ ii ], alternate_state_,
687  neighbors_curr_state_sparse_info_[ ii ], alt_state_sparse_mat_info_ );
688  }
689 
690  for (int ii = get_num_edges_to_smaller_indexed_nodes() + 1; ii <= get_num_incident_edges(); ++ii) {
691  alternate_state_two_body_energies_[ ii ] = get_incident_dlazy_edge(ii)->
692  get_two_body_energy_smi(
693  alternate_state_, neighbors_curr_state_[ ii ],
694  alt_state_sparse_mat_info_, neighbors_curr_state_sparse_info_[ ii ] );
695  }
696 
697  for ( int ii = 1; ii <= get_num_incident_edges(); ++ii ) {
698  alternate_state_total_energy_ += alternate_state_two_body_energies_[ ii ];
699  }
700  return alternate_state_total_energy_ - curr_state_total_energy_;
701 
702 
703 }
704 
705 ////////////////////////////////////////////////////////////////////////////////
706 /// @begin DoubleLazyNode::get_sparse_mat_info_for_curr_state
707 ///
708 /// @brief
709 ///
710 /// @detailed
711 ///
712 /// @param
713 ///
714 /// @global_read
715 ///
716 /// @global_write
717 ///
718 /// @remarks
719 ///
720 /// @references
721 ///
722 /// @authors apl
723 ///
724 /// @last_modified
725 ////////////////////////////////////////////////////////////////////////////////
726 inline
727 SparseMatrixIndex const &
729 {
731 }
732 
733 
734 ////////////////////////////////////////////////////////////////////////////////
735 /// @begin DoubleLazyNode::acknowledge_neighbors_state_substitution
736 ///
737 /// @brief
738 ///
739 /// @detailed
740 ///
741 /// @param
742 ///
743 /// @global_read
744 ///
745 /// @global_write
746 ///
747 /// @remarks
748 ///
749 /// @references
750 ///
751 /// @authors apl
752 ///
753 /// @last_modified
754 ////////////////////////////////////////////////////////////////////////////////
755 inline
756 void
758  int edge_to_altered_neighbor,
759  core::PackerEnergy new_edge_energy,
760  int other_node_new_state,
761  SparseMatrixIndex const & other_node_new_state_sparse_info
762 )
763 {
765  new_edge_energy - curr_state_two_body_energies_[edge_to_altered_neighbor];
766  curr_state_two_body_energies_[edge_to_altered_neighbor] = new_edge_energy;
767  neighbors_curr_state_[ edge_to_altered_neighbor ] = other_node_new_state;
768  neighbors_curr_state_sparse_info_[ edge_to_altered_neighbor ] =
769  other_node_new_state_sparse_info;
770  return;
771 }
772 
773 
774 }
775 }
776 }
777 
778 #endif
779 
780