Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DoubleDensePDInteractionGraph.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/DoubleDensePDInteractionGraph.hh
11 /// @brief Double-The-Memory interaction graph which stores interaction energies
12 /// for a rotamer and all of its neighbors in a single row in memory.
13 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
14 
15 
16 #ifndef INCLUDED_core_pack_interaction_graph_DoubleDensePDInteractionGraph_hh
17 #define INCLUDED_core_pack_interaction_graph_DoubleDensePDInteractionGraph_hh
18 
19 // Unit headers
21 
22 // Package Headers
23 
26 
27 //STL Headers
28 // AUTO-REMOVED #include <vector>
29 #include <list>
30 
31 //ObjexxFCL Headers
32 #include <ObjexxFCL/FArray1D.hh>
33 #include <ObjexxFCL/FArray2D.hh>
34 
35 #include <ObjexxFCL/FArray2.hh>
36 
37 
38 namespace core {
39 namespace pack {
40 namespace interaction_graph {
41 
42 class DoubleDensePDNode;
43 class DoubleDensePDEdge;
44 class DoubleDensePDInteractionGraph;
45 
47 {
48 public:
49  DoubleDensePDNode(InteractionGraphBase * owner, int node_id, int num_states);
50  virtual ~DoubleDensePDNode();
51  virtual void print() const;
52 
53  void update_one_body_energy( int state, core::PackerEnergy energy );
54  virtual void update_one_body_energies( ObjexxFCL::FArray1< core::PackerEnergy > & energies );
55  void add_to_one_body_energy( int state, core::PackerEnergy energy );
56  virtual void add_to_one_body_energies( ObjexxFCL::FArray1< core::PackerEnergy > & energies );
57  virtual void zero_one_body_energies();
59 
60  virtual void prepare_for_simulated_annealing();
61  //virtual unsigned int getMemoryUsageInBytes() const;
62 
63  void assign_zero_state();
64  virtual bool state_unassigned() const { return current_state_ == 0;}
65  void assign_state(int new_state);
66  int get_current_state() const;
69  (
70  int alternate_state,
71  core::PackerEnergy & prev_node_energy
72  );
74 
75  // <directed_design>
76  /* void project_deltaE_for_substitution
77  (
78  int alternate_state,
79  core::PackerEnergy & deltaE_unweighted,
80  core::PackerEnergy & prevE_unweighted,
81  core::PackerEnergy & deltaE_weighted,
82  core::PackerEnergy & prevE_weighted,
83  ObjexxFCL::FArray2D< core::PackerEnergy > const& weights
84  ); */
85 
86  //core::PackerEnergy get_weighted_energy_with_higher_indexed_nodes(ObjexxFCL::FArray2D< core::PackerEnergy > const& weights) const;
87  // </directed_design>
88 
89  inline
91  int edge_to_altered_neighbor,
92  core::PackerEnergy new_edge_energy,
93  int other_node_new_state);
94 
95  void print_internal_energies() const;
96 
98 
99  /*
100  void prepare_to_write_to_file();
101  void initialize_aa_for_state_array();
102  void clean_up_after_writing_to_file();
103  void prepare_to_read_energies_from_file( int num_states_for_node_in_file );
104  void clean_up_after_reading_energies_from_file();
105 
106  void set_aa_for_file_state(int file_state, int aa );
107  void set_instance_state_correspondence( int instance_state, int state_from_file );
108  int get_correspondence_for_state( int instance_state );
109 
110  int get_num_rots_absent_from_file();
111  void get_absent_rots( ObjexxFCL::FArray1DB_int & rots_absent );
112 
113  int get_num_states_in_file();
114  int & get_aatypes_for_file_states();
115 
116  int & get_aatypes_for_states();
117  int & get_num_file_states_for_aa();
118  int & get_file_states_2_instance_states_array();
119 
120  bool get_node_corresponded_to_file_node();
121  */
122 
123  virtual unsigned int count_static_memory() const;
124  virtual unsigned int count_dynamic_memory() const;
125 
126 protected:
128 
129 private:
130 
131  inline
133  {
134  return ( DoubleDensePDEdge* ) get_incident_edge( index ); // c-style cast since static_cast won't compile
135  }
136 
137  inline
139  {
140  return ( DoubleDensePDNode* ) get_adjacent_node( index );
141  }
142 
143  inline
145  {
146  return ( DoubleDensePDInteractionGraph* ) get_owner(); // c-style cast since static_cast won't compile
147  }
148 
149  std::vector< core::PackerEnergy > one_body_energies_;
150 
151  std::vector< int > neighbors_curr_state_;
153  std::vector< int > neighbors_num_states_;
154  std::vector< int > neighbors_rotindex_offset_;
155  ObjexxFCL::FArray2D< core::PackerEnergy > rotamer_energies_; // dim1: index of neighbor state, dim2 index of my state
156 
160  std::vector< core::PackerEnergy > curr_state_two_body_energies_;
161 
165  std::vector< core::PackerEnergy > alternate_state_two_body_energies_;
166 
168 
169  //no default constructor, uncopyable
173 };
174 
176 {
177 public:
178  DoubleDensePDEdge(InteractionGraphBase* owner, int first_node_ind, int second_node_ind);
179  virtual ~DoubleDensePDEdge();
180  virtual void set_sparse_aa_info(ObjexxFCL::FArray2_bool const & ) {}
181  virtual bool get_sparse_aa_info( int, int) const {return true;} //"all amino acids are neighbors"
182  virtual void add_to_two_body_energy(int const, int const, core::PackerEnergy const);
183  virtual void
184  add_to_two_body_energies( ObjexxFCL::FArray2< core::PackerEnergy > const & res_res_energy_array );
185  virtual
186  void set_two_body_energy(int const, int const, core::PackerEnergy const);
187  virtual
188  void clear_two_body_energy(int const, int const);
189  virtual core::PackerEnergy get_two_body_energy( int const, int const ) const;
190 
191  virtual void force_aa_neighbors(int, int) {} //all aa's are already neighbors -- dense representation
192  virtual void force_all_aa_neighbors() {} //same thing
193 
194 
195  virtual void declare_energies_final();
196  virtual void prepare_for_simulated_annealing();
197  //virtual unsigned int getMemoryUsageInBytes() const;
198 
200 
202  int node_ind,
203  int new_state,
204  core::PackerEnergy & new_energy
205  );
206  void acknowledge_state_zeroed( int node_ind );
207 
208  static
209  inline
211  int first_node_state,
212  int second_node_state,
213  ObjexxFCL::FArray2< core::PackerEnergy > & edge_energy_table
214  );
215 
216  inline void acknowledge_substitution(
217  int substituted_node_index,
218  core::PackerEnergy const curr_state_energy,
219  int nodes_new_state
220  );
221 
222  int get_two_body_table_size() const;
223  //ObjexxFCL::FArray2Da< core::PackerEnergy > get_edge_table_ptr();
224 
225  virtual unsigned int count_static_memory() const;
226  virtual unsigned int count_dynamic_memory() const;
227 
228  virtual void set_edge_weight( Real weight );
229 
230 private:
231  inline
232  DoubleDensePDNode* get_dpd_node( int index ) const
233  {
234  return (DoubleDensePDNode*) get_node( index ); //c-style cast since static_cast won't compile
235  }
236 
237  inline
239  {
240  return (DoubleDensePDInteractionGraph*) get_owner(); //c-style cast since static_cast won't compile
241  }
242 
243  ObjexxFCL::FArray2D< core::PackerEnergy > two_body_energies_; //Dense matrix
246 
247  //no default constructor, uncopyable
251 };
252 
254 {
255 public:
256  DoubleDensePDInteractionGraph(int num_nodes);
257  virtual void initialize( rotamer_set::RotamerSetsBase const & rot_sets );
258 
259  virtual core::PackerEnergy get_one_body_energy_for_node_state( int node, int state);
260 
261  //virtual void set_num_aatypes(int) {}
262  virtual int get_num_aatypes() const {return 1;}
263 
264  virtual void blanket_assign_state_0();
265  virtual core::PackerEnergy set_state_for_node(int node_ind, int new_state);
266  virtual core::PackerEnergy set_network_state( ObjexxFCL::FArray1_int & node_states);
267  virtual void consider_substitution
268  (
269  int node_ind,
270  int new_state,
271  core::PackerEnergy & delta_energy,
272  core::PackerEnergy & prev_energy_for_node
273  );
274 
275  /// @brief Accepts (commits) the state change previously considered in a call to
276  /// consider_substitution and returns the energy of the entire graph
278 
279  /// @brief removes all accumulated numerical drift and returns the
280  /// energy for the current state assignment.
282  /// @brief returns the number of floats used in all edge two-body energy tables
283  virtual int get_edge_memory_usage() const;
284 
285  /// @brief outputs the current state for each node, useful for debugging
286  virtual void print_current_state_assignment() const;
288 
289  /// @brief a user may define subsets of the vertex set for which they would like to
290  /// know the internal energy sum.
291  virtual core::PackerEnergy get_energy_sum_for_vertex_group( int group_id );
292 
293  virtual unsigned int count_static_memory() const;
294  virtual unsigned int count_dynamic_memory() const;
295 
296 protected:
297  //virtual unsigned int getMemoryUsageInBytes() const;
298 
299  virtual NodeBase* create_new_node( int node_index, int num_states);
300  virtual EdgeBase* create_new_edge( int index1, int index2);
301 
302  /// @brief removes numerical drift that can accumulate over the course of
303  /// many state assignment changes within simulated annealing
305 
306  inline
307  DoubleDensePDNode* get_dpd_node(int index) const
308  {
309  return (DoubleDensePDNode*) get_node( index );
310  }
311 
312 private:
317 
318  static const int COMMIT_LIMIT_BETWEEN_UPDATES = 1024; // 2^10
319 
320  //no default constructor, uncopyable
324 };
325 
326 /// @brief returns the change in energy that would be induced by switching this node
327 /// from its current state into another state
328 ///
329 /// iterates across the incident edges for a node in two phases:
330 /// in the first phase, it examines edges leading to higher-indexed nodes
331 /// in the second phase, it examines edges leading to smaller-indexed nodes.
332 /// for cache efficiency, all of the amino-acid-neighbor-offset information
333 /// that each edge calculates is stored on the nodes themselves. The edges
334 /// are never touched; rather, their private information is stored on the nodes
335 /// and handed to static member functions of the DoubleDensePDEdge class. This "store
336 /// edge information on the nodes" strategy gives me performance equivalent
337 /// to the previous energy2b lookup tables.
338 ///
339 /// @param alternate_state - [in] - the alternate state to consider
340 /// @param previous_energy_for_node - [out] - the old energy1b/energy2b sum for this
341 /// node; used by simulate annealing.
342 ///
343 inline
346  int alternate_state,
347  core::PackerEnergy & prev_energy_for_node
348 )
349 {
350 
352  //std::cerr << "proj_deltaE: node - " << get_node_index()
353  //<< " alt state " << alternate_state << "...";
354 
355  alternate_state_ = alternate_state;
358  prev_energy_for_node = curr_state_total_energy_;
359 
360  if ( get_num_incident_edges() == 0 ) {
362  }
363  int const altstate_offset = rotamer_energies_.index( 1, alternate_state_ ) - 1;
364 
365  for (int ii = 1; ii <= get_num_incident_edges(); ++ii) {
367  altstate_offset + neighbors_curr_state_plus_offset_[ ii ] ];
368  //alternate_state_total_energy_ += alternate_state_two_body_energies_[ ii ];
369  //std::cerr << " edge " << ii << " E= " << alternate_state_two_body_energies_[ ii ];
370  }
371 
372  for (int ii = 1; ii <= get_num_incident_edges(); ++ii) {
373  //alternate_state_two_body_energies_[ ii ] = rotamer_energies_[
374  // altstate_offset + neighbors_curr_state_plus_offset_[ ii ] ];
376  //std::cerr << " edge " << ii << " E= " << alternate_state_two_body_energies_[ ii ];
377  }
378 
379  //std::cerr<< "..done" << std::endl;
380 
382 
383 }
384 
385 /// @brief updates bookkeeping arrays for when a neighbor has changed its state
386 ///
387 /// @param edge_to_altered_neighbor - [in] - the index for the edge that connects
388 /// this node to the node that just changed its state
389 /// @param new_edge_energ - [in] - the pair energy between this node in its current
390 /// state and the new state of the node that just changed its state
391 /// @param other_node_new_state - [in] - the state the neighbor just adopted
392 inline
394  int edge_to_altered_neighbor,
395  core::PackerEnergy new_edge_energy,
396  int other_node_new_state
397 )
398 {
399 
401  new_edge_energy - curr_state_two_body_energies_[edge_to_altered_neighbor];
402  curr_state_two_body_energies_[edge_to_altered_neighbor] = new_edge_energy;
403  neighbors_curr_state_[ edge_to_altered_neighbor ] = other_node_new_state;
404  neighbors_curr_state_plus_offset_[ edge_to_altered_neighbor ] = other_node_new_state + neighbors_rotindex_offset_[ edge_to_altered_neighbor ];
405  return;
406 }
407 
408 /// @brief static method that looks up the two body energy when the
409 /// node with the smaller index on an edge is considering an alternate state
410 ///
411 /// @param first_node_alt_state - [in] - the alternate state for the lower-indexed node
412 /// @param second_node_orig_state - [in] - the current state for the higher-indexed node
413 /// @param edge_energy_table - [in] - the proxy FArray pointing at the edge table
414 /// connecting the two nodes.
415 inline
418  int first_node_state,
419  int second_node_state,
420  ObjexxFCL::FArray2< core::PackerEnergy > & edge_energy_table
421 )
422 {
423  if (first_node_state == 0 || second_node_state == 0) {
424  return 0.0f;
425  } else {
426  return edge_energy_table( second_node_state, first_node_state );
427  }
428 }
429 
430 
431 /// @brief update bookkeeping information when one of the nodes an edge is incident
432 /// upon changes state
433 ///
434 /// @param substituted_node_index - [in] - index of the node that chagned its state
435 /// @param curr_state_energy - [in] - the two body energy given the new state
436 /// @param nodes_new_state - [in] - the state the node just transitioned into
437 /// @param nodes_new_state_sparse_info - [in] - sparse matrix info for the new state
438 inline
439 void
441  int substituted_node_index,
442  core::PackerEnergy const curr_state_energy,
443  int nodes_new_state
444 )
445 {
446  int node_substituted = substituted_node_index == get_node_index(0) ? 0 : 1;
447  int node_not_substituted = ! node_substituted;
448 
449  curr_state_energy_ = curr_state_energy;
450 
451  get_dpd_node( node_not_substituted )->
452  acknowledge_neighbors_state_substitution
453  (
454  get_edges_position_in_nodes_edge_vector( node_not_substituted ),
456  nodes_new_state
457  );
458 }
459 
460 
461 
462 } // namespace interaction_graph
463 } // namespace pack
464 } // namespace core
465 
466 #endif