Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FASTERAnnealer.cc
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/annealer/FASTERAnnealer.hh
11 /// @brief
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 // Unit headers
16 
17 // Package headers
21 
22 // Numeric headers
23 #include <numeric/random/random.hh>
24 #include <numeric/random/random_permutation.hh>
25 
26 // ObjexxFCL headers
27 #include <ObjexxFCL/FArray1A.hh>
28 
29 // C++ headers
30 #include <iostream>
31 // AUTO-REMOVED #include <ctime>
32 
33 #include <utility/vector0.hh>
34 #include <utility/vector1.hh>
35 
36 
37 namespace core {
38 namespace pack {
39 namespace annealer {
40 
41 static numeric::random::RandomGenerator RG(133780); // <- Magic number, do not change it!!!
42 
44  ObjexxFCL::FArray1D_int & bestrotamer_at_seqpos,
45  core::PackerEnergy & bestenergy,
46  bool start_with_current, // start simulation with current rotamers
48  FixbbRotamerSetsCOP rotamer_sets,
49  ObjexxFCL::FArray1_int & current_rot_index,
50  bool calc_rot_freq,
51  ObjexxFCL::FArray1D< core::PackerEnergy > & rot_freq
52 ):
53  parent(
54  ig->get_num_total_states(),
55  bestrotamer_at_seqpos,
56  bestenergy,
57  start_with_current, // start simulation with current rotamers
58  rotamer_sets,
59  current_rot_index,
60  calc_rot_freq,
61  rot_freq
62  ),
63  ig_(ig),
64  rotamer_sets_( rotamer_sets ),
65  num_nodes_( ig_->get_num_nodes() ),
66  recent_network_state_history_( num_nodes_, recent_history_size_, 0 ),
67  recent_history_hash_values_( recent_history_size_, 0 ),
68  recent_history_hash_count_( hash_size_, 0 ),
69  recent_history_head_( 0 ),
70  curr_in_recent_history_( 0 ),
71  netstate_duplicated_( false ),
72  progress_through_sBR_( -1 ),
73  sBR_rotamers_( ig_->get_num_total_states() ),
74  ciBR_only_( false ),
75  num_sa_trajectories_( 5 ),
76  sa_inner_iterations_length_scale_( 0.05 ),
77  sBR_limit_( -1 )
78  //rot_2_moltenres_( 2,ig_->get_num_total_states(), 0)
79 {
80  for (unsigned int ii =1; ii <= sBR_rotamers_.size(); ++ii) {
81  sBR_rotamers_[ ii-1 ] = ii;
82  }
83 }
84 
86 
87 void
89 {
90  if ( ig_->get_num_total_states() == 0 ) {
91  return;
92  }
93 
94  if ( ciBR_only_ ) {
95  ig_->prepare_for_FASTER();
96  ig_->blanket_assign_state_0();
97  ig_->assign_BMEC();
98  if ( ig_->any_vertex_state_unassigned()) {
99  std::cout << "Failed to assign BMEC; some vertices have 0 states" << std::endl;
100  }
101  //ciBR();
102  sBR();
104  bestenergy() = ig_->get_energy_current_state_assignment();
105  finalize_output();
106  return;
107  }
108 
109  core::PackerEnergy best_energy( 0.0 );
110  ObjexxFCL::FArray1D_int best_network_state( num_nodes_, 0 );
111  ObjexxFCL::FArray1D_int dummy( num_nodes_, 0 );
112 
113  //clock_t starttime = clock();
114 
115  for (int ii = 1; ii <= num_sa_trajectories_; ++ii ) {
116  { // scope
117  FixbbSimAnnealer fixbb_annealer(
119  bestenergy(),
120  false,
121  ig_,
123  dummy,
124  calc_rot_freq(),
125  rot_freq()
126  );
128  fixbb_annealer.set_assign_state_to_all_nodes_immediately( true );
129  fixbb_annealer.run();
130  }
131 
132  if ( ii == 1 || best_energy > ig_->get_energy_current_state_assignment() ) {
133  ig_->get_current_network_state( best_network_state );
134  //std::cout << "Best network state:";
135  //for ( Size jj = 1; jj <= best_network_state.size(); ++jj ) {
136  // std::cout << " " << best_network_state( jj );
137  //}
138  //std::cout << std::endl;
139  best_energy = ig_->get_energy_current_state_assignment();
140  }
141 
142  ig_->prepare_for_FASTER();
143  core::PackerEnergy energy = ig_->get_energy_current_state_assignment();
144  //std::cout << "Energy following quick-and-dirty sim annealing: " << energy << std::endl;
145  //std::cout << "FASTER::run -- bestenergy: " << best_energy << std::endl;
146 
147  sBR();
148  energy = ig_->get_energy_current_state_assignment();
149  if ( energy < best_energy ) {
150  //std::cout << "Found a better energy after completing sBR on rotamer assignment from Fixbb Sim Annealer: " << best_energy << std::endl;
151  best_energy = energy;
152  ig_->get_current_network_state( best_network_state );
153  //for (int jj = 1; jj <= num_nodes_; ++jj)
154  //{
155  // if ( best_network_state( jj ) < 100 ) std::cout << " ";
156  // if ( best_network_state( jj ) < 10 ) std::cout << " ";
157  // std::cout << best_network_state( jj ) << " ";
158  // if ( jj == 20 ) std::cout << std::endl;
159  //}
160  //std::cout << std::endl;
161  }
162  }
163 
164  //for (int jj = 1; jj <= num_nodes_; ++jj)
165  //{
166  // std::cout << "best network state " << std::endl;
167  // if ( best_network_state( jj ) < 100 ) std::cout << " ";
168  // if ( best_network_state( jj ) < 10 ) std::cout << " ";
169  // std::cout << best_network_state( jj ) << " ";
170  // if ( jj == 20 ) std::cout << std::endl;
171  //}
172  //std::cout << std::endl;
173 
174  ig_->set_network_state( best_network_state );
175  bestenergy() = ig_->get_energy_current_state_assignment();
176  //std::cout << "FASTER: bestenergy() " << bestenergy() << std::endl;
177 
178  //clock_t stoptime = clock();
179  //std::cout << "FASTER completed in " << ((double) stoptime-starttime )/CLOCKS_PER_SEC << " seconds." << std::endl;
180 
181  finalize_output();
182 }
183 
184 
185 void
187 {
189  ObjexxFCL::FArray1D_int current_network_state( num_nodes_, 0 );
190 
191  while ( ! stuck_in_network_state_loop() )
192  {
193  ig_->relax_in_current_context();
194  ig_->commit_relaxation();
195 
196  //core::PackerEnergy total_energy = ig_->get_energy_current_state_assignment();
197  //std::cout << "iBR: total_energy = " << total_energy << std::endl;
198  ig_->get_current_network_state( current_network_state );
199  note_current_network_state( current_network_state );
200  }
201 
202 }
203 
204 void
206 {
207 
208  ObjexxFCL::FArray1D_int iBRstate( ig_->get_num_nodes() );
209  ig_->get_current_network_state( iBRstate );
210 
211  ObjexxFCL::FArray1D_int best_ciBRs_state( ig_->get_num_nodes() );
212  core::PackerEnergy best_energy = 0;
213 
214  for (int ii = 1; ii < 10; ++ii)
215  {
216  ig_->set_network_state( iBRstate );
217  ciBR();
218  core::PackerEnergy ciBR_energy = ig_->get_energy_current_state_assignment();
219  if ( ii == 1 || ciBR_energy < best_energy )
220  {
221  ig_->get_current_network_state( best_ciBRs_state );
222  best_energy = ciBR_energy;
223  }
224  }
225  //std::cout << "ciBR finished with best energy: " << best_energy << std::endl;
226  ig_->set_network_state( best_ciBRs_state );
227 }
228 
229 void
231 {
232  Real const DESMET_ciBR_ACCEPT_RATE = 0.8;
233  int const limit = 2000; // ??
234 
236  ObjexxFCL::FArray1D_int current_network_state( num_nodes_, 0 );
237  ObjexxFCL::FArray1D_int best_network_state( num_nodes_, 0 );
238  core::PackerEnergy ciBR_best_energy( 0 );
239 
240  int count = 0;
241  while ( ! stuck_in_network_state_loop() ) {
242  ++count;
243  if ( count == limit ) break;
244 
245  ig_->relax_in_current_context();
246  ig_->probabilistically_commit_relaxation( DESMET_ciBR_ACCEPT_RATE );
247  //core::PackerEnergy total_energy = ig_->get_energy_current_state_assignment();
248  //std::cout << "ciBR: total_energy = " << total_energy << std::endl;
249 
250  ig_->get_current_network_state( current_network_state );
251 
252  note_current_network_state( current_network_state );
253  if ( count == 1 || ig_->get_energy_current_state_assignment() < ciBR_best_energy ) {
254  ciBR_best_energy = ig_->get_energy_current_state_assignment();
255  best_network_state = current_network_state;
256  }
257  }
258  ig_->set_network_state( best_network_state );
259 }
260 
261 void
263 {
265  int numAttemptsSinceLastCommit = 0;
266 
267  int num_rotamers = static_cast< int > (sBR_rotamers_.size());
268 
269  core::PackerEnergy last_energy = ig_->get_energy_current_state_assignment();
270  int count_sBR = 0;
271  while ( numAttemptsSinceLastCommit != num_rotamers ) {
272  ++numAttemptsSinceLastCommit;
273 
274  int ran_rotamer = pick_a_rotamer_for_sBR();
275  int const node = rotamer_sets_->moltenres_for_rotamer( ran_rotamer );
276  int const ran_rotamer_on_node = rotamer_sets_->rotid_on_moltenresidue( ran_rotamer );
277 
278  if ( ran_rotamer_on_node == ig_->get_current_state_for_node( node ) ) continue;
279  ++count_sBR;
280 
281  core::PackerEnergy deltaE = ig_->perturb_sBR_and_relax( node, ran_rotamer_on_node );
282 
283  //core::PackerEnergy alt_total_energy = ig_->get_energy_following_relaxation();
284  //std::cout << "last: " << last_energy << " deltaE: " << deltaE << " last+deltaE: ";
285  //std::cout << last_energy + deltaE << " ig's version: " << alt_total_energy << std::endl;
286 
287 
288  if ( deltaE < 0.001 ) {
289  core::PackerEnergy total_energy = ig_->get_energy_following_relaxation();
290 
291  if ( total_energy < last_energy ) {
292  //if (deltaE > 0 ) std::cout << "Numerical instability in deltaE calculation?" << deltaE << " " << total_energy << std::endl;
293 
294  last_energy = total_energy;
295  ig_->commit_relaxation();
296  numAttemptsSinceLastCommit = 0;
298  //std::cout << "sBR commit relaxation: total_energy = " << last_energy << std::endl;
299  } else {
300  ig_->reject_perturbation();
301  }
302 
303  } else {
304  ig_->reject_perturbation();
305  }
306  if ( sBR_limit_ != -1 && count_sBR >= sBR_limit_ ) {
307  break;
308  }
309 
310  }
311  //std::cout << "sBR finished: best_energy = " << last_energy << " in " << count_sBR << " steps; nrot= " << num_rotamers << std::endl;
312 
313 }
314 
315 void
317 {
318  core::PackerEnergy last_energy = ig_->get_energy_current_state_assignment();
319  for (int ii = 1; ii < 10000; ++ii) {
320  int node1 = ((int) ( RG.uniform() * num_nodes_)) + 1;
321  int node2 = ig_->get_random_neighbor_for_node( node1 );
322 
323  if (node2 == 0) continue;
324 
325  int rot1 = pick_rotamer_for_node( node1 );
326  int rot2 = pick_rotamer_for_node( node2 );
327 
328  core::PackerEnergy deltaE = ig_->perturb_dBR_and_relax( node1, rot1, node2, rot2 );
329 
330  if ( deltaE < 0.001 ) {
331  core::PackerEnergy total_energy = ig_->get_energy_following_relaxation();
332  if ( total_energy < last_energy ) {
333  last_energy = total_energy;
334  ig_->commit_relaxation();
335  //std::cout << "dBR commit relaxation: total_energy = " << last_energy << std::endl;
336  } else {
337  ig_->reject_perturbation();
338  }
339  } else {
340  ig_->reject_perturbation();
341  }
342  }
343  //std::cout << "dBR finished: best_energy = " << last_energy << std::endl;
344 }
345 
346 void FASTERAnnealer::set_ciBR_only( bool setting )
347 {
348  ciBR_only_ = setting;
349 }
350 
352 {
353  num_sa_trajectories_ = setting;
354 }
355 
357 {
359 }
360 
361 
362 void
364 {
365 
366  ObjexxFCL::FArray1D_int best_state_on_node( num_nodes_, 0 );
367  ig_->get_current_network_state( best_state_on_node );
368 
369  //convert best_state_on_node into best_rotamer_at_seqpos
370  for ( Size ii = 1; ii <= rotamer_sets_->nmoltenres(); ++ii){
371  int const iiresid = rotamer_sets_->moltenres_2_resid( ii );
372  bestrotamer_at_seqpos()( iiresid ) = rotamer_sets_->moltenres_rotid_2_rotid( ii, best_state_on_node(ii));
373  }
374 
375 }
376 
377 void
379 {
385  netstate_duplicated_ = false;
386 }
387 
388 void
389 FASTERAnnealer::note_current_network_state( ObjexxFCL::FArray1_int const & netstate )
390 {
394 
395  } else {
399  }
401 
402  }
403 
404  ObjexxFCL::FArray1A_int history_line( recent_network_state_history_( 1, recent_history_head_ ), num_nodes_ );
405  history_line = netstate;
406 
408  int num_same_hash = recent_history_hash_count_( hash );
409  if ( num_same_hash != 0 ) {
410  //possible duplicate: stupid, slow method -- look at them all
411  for (int ii = 1; ii <= curr_in_recent_history_; ++ii) {
412  if ( recent_history_head_ == ii ) continue;
413  if ( hash == recent_history_hash_values_( ii ) ) {
414  --num_same_hash;
415  bool same = true;
416  for (int jj = 1; jj <= num_nodes_; ++jj ) {
418  recent_network_state_history_( jj, ii ) ) {
419  same = false;
420  break;
421  }
422  }
423  if ( same ) {
424  netstate_duplicated_ = true;
425  break;
426  }
427 
428  if ( num_same_hash == 0 ) {
429  break;
430  }
431  }
432  }
433  }
434 
436  ++recent_history_hash_count_( hash );
437 
438 }
439 
440 bool
442 {
443  return netstate_duplicated_;
444 }
445 
446 void
448 {
449  ObjexxFCL::FArray1D_int state_on_node( ig_->get_num_nodes(), 0 );
450  ig_->get_current_network_state( state_on_node );
451  int count_since_last_commit( 0 );
452  int count_total( 0 );
453  int num_rotamers = static_cast< int > (sBR_rotamers_.size());
454 
455  core::PackerEnergy deltaE, dummy, best_energy( ig_->get_energy_current_state_assignment() );
456 
457  set_to_quench();
458 
459 
460  while ( count_since_last_commit < num_rotamers ) {
461  ++count_since_last_commit;
462  ++count_total;
463 
464  int ran_rotamer = pick_a_rotamer( count_total );
465  int const node = rotamer_sets_->moltenres_for_rotamer( ran_rotamer );
466  int const ran_rotamer_on_node = rotamer_sets_->rotid_on_moltenresidue( ran_rotamer );
467 
468  if ( state_on_node( node ) == ran_rotamer_on_node ) continue;
469 
470  ig_->consider_substitution( node, ran_rotamer_on_node, deltaE, dummy );
471  if ( state_on_node( node ) == 0 || deltaE < 0 ) {
472  core::PackerEnergy totalE = ig_->commit_considered_substitution();
473  state_on_node( node ) = ran_rotamer_on_node;
474  if ( totalE + 1e-4 < best_energy) {
475  count_since_last_commit = 0;
476  best_energy = totalE;
477  }
478  }
479 
480  if ( count_since_last_commit > 2*num_rotamers ) {
481  break;
482  }
483  }
484 
486 
487 }
488 
489 
490 int
492 {
493  int num_states_for_node = ig_->get_num_states_for_node( node );
494  int rand_state = ((int) ( RG.uniform() * num_states_for_node ) ) + 1;
495  return rand_state;
496 }
497 
498 int
500 {
503 }
504 
505 void
507 {
509  numeric::random::random_permutation( sBR_rotamers_.begin(), sBR_rotamers_.end(), RG );
510 }
511 
512 int
514 {
515  int hash = 0;
516  for ( int ii = 1; ii <= num_nodes_; ++ii) {
517  hash += ii * recent_network_state_history_( ii, history_index );
518  hash = hash % hash_size_;
519  }
520  return hash;
521 }
522 
523 }
524 }
525 }
526 
527