Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MultiCoolAnnealer.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/MultiCoolAnnealer.cc
11 /// @brief Multiple low-temperature cooling cycles annealer class definition
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 /// Unit headers
16 
17 /// Package headers
18 // AUTO-REMOVED #include <core/pack/rotamer_set/RotamerSets.hh>
19 // AUTO-REMOVED #include <core/pack/rotamer_set/RotamerSet.hh>
22 
23 /// ObjexxFCL headers
24 // AUTO-REMOVED #include <ObjexxFCL/Fmath.hh>
25 #include <ObjexxFCL/FArray1A.hh>
26 
27 /// Utility headers
28 #include <utility/exit.hh>
29 
30 // Numeric headers
31 #include <numeric/random/random.hh>
32 
33 /// C++ headers
34 #include <iostream>
35 
36 #include <utility/vector0.hh>
37 #include <utility/vector1.hh>
38 
39 //Auto Headers
41 #ifdef WIN32
42 #include <ctime>
43 #endif
44 
45 static numeric::random::RandomGenerator mca_RG(42411); // <- Magic number, do not change it!!!
46 
47 namespace core {
48 namespace pack {
49 namespace annealer {
50 
51 using namespace ObjexxFCL;
52 using namespace pack::interaction_graph;
53 using namespace pack::rotamer_set;
54 using namespace pack::task;
55 
57 
58 /// @brief constructor
60  PackerTaskCOP task,
61  utility::vector0< int > & rot_to_pack,
62  FArray1D_int & bestrotamer_at_seqpos,
63  core::PackerEnergy & bestenergy,
64  bool start_with_current, // start simulation with current rotamers
66  FixbbRotamerSetsCOP p_rotamer_set,
67  FArray1_int & current_rot_index,
68  bool calc_rot_freq,
69  FArray1D< core::PackerEnergy > & rot_freq
70 ):
71  RotamerAssigningAnnealer(
72  rot_to_pack,
73  (int) rot_to_pack.size(),
74  bestrotamer_at_seqpos,
75  bestenergy,
76  start_with_current, // start simulation with current rotamers
77  p_rotamer_set,
78  current_rot_index,
79  calc_rot_freq,
80  rot_freq
81  ),
82  ig_(ig),
83  nsteps_for_rot_( p_rotamer_set->nrotamers() , 0 ),
84  nsteps_( 0 ),
85  top_to_keep( task->multi_cool_annealer_history_size() ),
86  top_netstates_( ig_->get_num_nodes(), top_to_keep, 0 ),
87  energy_top_( top_to_keep, uninitialized_energy ),
88  worst_top_energy_( uninitialized_energy ),
89  which_netstate_worst_top_( 1 ),
90  num_top_kept_( 0 )
91 {
92 }
93 
95  PackerTaskCOP task,
96  FArray1D_int & bestrotamer_at_seqpos,
97  core::PackerEnergy & bestenergy,
98  bool start_with_current, // start simulation with current rotamers
100  FixbbRotamerSetsCOP p_rotamer_set,
101  FArray1_int & current_rot_index,
102  bool calc_rot_freq,
103  FArray1D< core::PackerEnergy > & rot_freq
104 ):
105  RotamerAssigningAnnealer(
106  (ig->get_num_total_states()),
107  bestrotamer_at_seqpos,
108  bestenergy,
109  start_with_current, // start simulation with current rotamers
110  p_rotamer_set,
111  current_rot_index,
112  calc_rot_freq,
113  rot_freq
114  ),
115  ig_(ig),
116  nsteps_for_rot_( num_rots_to_pack(), 0 ),
117  nsteps_( 0 ),
118  top_to_keep( task->multi_cool_annealer_history_size() ),
119  top_netstates_( ig_->get_num_nodes(), top_to_keep, 0 ),
120  energy_top_( top_to_keep, uninitialized_energy ),
121  worst_top_energy_( uninitialized_energy ),
122  which_netstate_worst_top_( 1 ),
123  num_top_kept_( 0 )
124 {
125 }
126 
127 /// @brief virtual destructor
129 {}
130 
131 
132 /// @brief sim_annealing for fixed backbone design mode
134 {
135 
136  //--------------------------------------------------------------------
137  //internal variables
138 
139  //FArray1D_int list( rotamer_sets()->nrotamers() );
140  FArray1D_int state_on_node( rotamer_sets()->nmoltenres(),0 );
141  FArray1D_int best_state_on_node( rotamer_sets()->nmoltenres(),0 );
142 
143 
144  //bk variables for calculating rotamer frequencies during simulation
145 
146  FArray1D_int network_state_to_restore( rotamer_sets()->nmoltenres() );
147  FArray1D< core::PackerEnergy > temp_top_generated_at( top_to_keep, 0.0f );
148  FArray1D< core::PackerEnergy > second_round_cooling_finalE( top_to_keep, 0.0f );
149  FArray2D_int hamming_distance( top_to_keep, top_to_keep, 0 );
150  FArray1D_int hamming_start_to_stop( top_to_keep, 0 );
151 
152  //unsigned int count_considered_rotamer_subs = 0;
153 
154  //--------------------------------------------------------------------
155  //initialize variables
156 
157 
158  ig_->prepare_for_simulated_annealing();
159  ig_->blanket_assign_state_0();
160 
161  //--------------------------------------------------------------------
162  if ( num_rots_to_pack() == 0 ) return;
163 
164 
165  /// Start off in some random state assignment to avoid unassigned-state problems that
166  /// are sometimes seen in optH
167  for ( int ii = 1; ii <= ig_->get_num_nodes(); ++ii ) {
168  float dummy_delta( 0.0 ), dummy_prev_energy( 0.0 );
169  if ( ig_->get_num_states_for_node( ii ) == 1 ) {
170  ig_->consider_substitution( ii, 1, dummy_delta, dummy_prev_energy );
171  ig_->commit_considered_substitution();
172  state_on_node( ii ) = 1;
173  } else {
174  int randstate = rotamer_sets()->rotid_on_moltenresidue( pick_a_rotamer_for_node( ii ));
175  ig_->consider_substitution( ii, randstate, dummy_delta, dummy_prev_energy );
176  ig_->commit_considered_substitution();
177  state_on_node( ii ) = randstate;
178  }
179  }
180  bestenergy() = ig_->get_energy_current_state_assignment();
181  best_state_on_node = state_on_node;
182 
183 
185 
186  int outeriterations = get_outeriterations() * 6;
187  //core::PackerEnergy last_temperature = 10;
188  //outer loop
189  set_temperature( 10 );
190  set_lowtemp( 0.2 );
191  for (int nn = 1; nn <= outeriterations; ++nn ) {
192 
193  if ( nn % 6 == 1 && nn != 1) {
194  cool();
195  }
196 
197  int inneriterations = get_inneriterations();
198  inneriterations /= 5;
199 
200  //std::cerr << "inneriterations: " << inneriterations << std::endl;
201 
202  if (nn % 2 == 0 ) {
203  //last_temperature = get_temperature();
204  network_state_to_restore = state_on_node;
205 
206  bestenergy() = ig_->get_energy_current_state_assignment();
207  best_state_on_node = state_on_node;
208  run_quench( state_on_node, best_state_on_node, bestenergy(), inneriterations );
209  store_top_energy( best_state_on_node, bestenergy() );
210 
211  state_on_node = network_state_to_restore;
212  ig_->set_network_state( state_on_node );
213  } else {
215  state_on_node,
216  best_state_on_node,
217  bestenergy(),
218  inneriterations);
219  store_top_energy( best_state_on_node, bestenergy() );
220  //std::cerr << "Temperature: " << get_temperature() << " bestenergy so far: " << bestenergy() << std::endl;
221  }
222 
223  //std::cerr << "Considered " << nsteps_ << " rotamer substitutions so far." << std::endl;
224  } //end of outeriteration loop
225 
226  { // scope
227 
228  core::PackerEnergy best_of_best = energy_top_( 1 );
229  int which_best_of_best = 1;
230  for ( Size ii = 2; ii <= top_to_keep; ++ii) {
231  if ( best_of_best > energy_top_( ii ) && energy_top_( ii ) != uninitialized_energy ) {
232  best_of_best = energy_top_( ii );
233  which_best_of_best = ii;
234  }
235  }
236  FArray1A_int best_of_best_state( top_netstates_( 1, which_best_of_best), rotamer_sets()->nmoltenres() );
237  best_state_on_node = best_of_best_state;
238  bestenergy() = best_of_best;
239  }
240 
241  set_lowtemp( 0.05 );
242  for ( Size ii = 1; ii <= top_to_keep; ++ii ) {
243  //clock_t starttime = clock();
244  //std::cout << "MultiCoolAnnealer: starting low temp annealing # "<< ii << " of " << top_to_keep << std::endl;
245  //std::cout << " with network state: " << std::endl;
246  //for ( int jj = 1; jj <= rotamer_sets()->nmoltenres(); ++jj )
247  //{
248  // int jjstate = top_netstates_(jj, ii );
249  // if ( jjstate < 1000 ) std::cerr << " ";
250  // if ( jjstate < 100 ) std::cerr << " ";
251  // if ( jjstate < 10 ) std::cerr << " ";
252  // std::cout << jjstate << " ";
253  // if ( jj % 10 == 0 ) std::cerr << std::endl;
254  //}
255  //std::cout << std::endl << "With energy: " << energy_top_( ii ) << std::endl;
256 
257  if ( energy_top_( ii ) == uninitialized_energy ) continue;
258 
259  FArray1A_int start_state( top_netstates_( 1, ii ), rotamer_sets()->nmoltenres() );
260  state_on_node = start_state;
261  ig_->set_network_state( state_on_node );
262  core::PackerEnergy best_energy_this_starting_point = energy_top_( ii );
263  FArray1D_int best_state_on_node_this_starting_point( rotamer_sets()->nmoltenres() );
264  best_state_on_node_this_starting_point = state_on_node;
265 
266  set_temperature( 0.25 );
267  outeriterations = 6;
268  int inneriterations = get_inneriterations();
269 
270  for (int nn = 1; nn <= outeriterations; ++nn ) {
271  if (nn != 1 ) cool();
272 
273  //std::cerr << "MultiCoolAnnealer: temperature = " << get_temperature() << " currenergy: ";
274  //std::cerr << ig_->get_energy_current_state_assignment() << std::endl;
275 
277  state_on_node,
278  best_state_on_node_this_starting_point,
279  best_energy_this_starting_point,
280  inneriterations);
281 
282  FArray1D_int state_to_restore( state_on_node );
283  //core::PackerEnergy bestE_before_quench( bestenergy() );
284  run_quench(
285  state_on_node,
286  best_state_on_node,
287  bestenergy(),
288  inneriterations / 2);
289  //if ( bestE_before_quench > bestenergy() )
290  //{
291  // std::cerr << "Quench inside cooling run # " << ii << " found lower energy: ";
292  // std::cerr << bestenergy() << std::endl;
293  //}
294  state_on_node = state_to_restore;
295  ig_->set_network_state( state_on_node );
296 
297  } // end outer iterations
298 
299  if ( std::abs(best_energy_this_starting_point - energy_top_( ii ) ) < 0.001 ) {
300  bool same_as_start = true;
301  for (Size jj = 1; jj <= rotamer_sets()->nmoltenres(); ++jj) {
302  if ( best_state_on_node_this_starting_point( jj ) != top_netstates_( jj, ii ) ) {
303  same_as_start = false;
304  break;
305  }
306  }
307 
308  if ( same_as_start ) {
309  //clock_t stoptime = clock();
310  //std::cout << "Round " << ii << " cooling completed in " << ((double) stoptime-starttime)/CLOCKS_PER_SEC << std::endl;
311  continue;
312  }
313  }
314 
315  state_on_node = best_state_on_node_this_starting_point;
316  ig_->set_network_state( state_on_node );
317  run_quench( state_on_node,
318  best_state_on_node_this_starting_point,
319  best_energy_this_starting_point,
320  inneriterations );
321 
322  second_round_cooling_finalE( ii ) = best_energy_this_starting_point;
323  for (Size jj = 1; jj <= rotamer_sets()->nmoltenres(); ++jj) {
324  if ( best_state_on_node_this_starting_point( jj ) != top_netstates_(jj, ii ) ) {
325  ++hamming_start_to_stop(ii);
326  }
327  }
328 
329  if ( bestenergy() > best_energy_this_starting_point ) {
330  //std::cerr << "BEST FOUND" << std::endl;
331  bestenergy() = best_energy_this_starting_point;
332  best_state_on_node = best_state_on_node_this_starting_point;
333  }
334 
335  //std::cerr << "MultiCoolAnnealer: final low temp annealing # "<< ii << " with network state: " << std::endl;
336  //for ( int jj = 1; jj <= rotamer_sets()->nmoltenres(); ++jj )
337  //{
338  // int jjstate = state_on_node(jj);
339  // if ( jjstate < 1000 ) std::cerr << " ";
340  // if ( jjstate < 100 ) std::cerr << " ";
341  // if ( jjstate < 10 ) std::cerr << " ";
342  // std::cerr << jjstate << " ";
343  // if ( jj % 10 == 0 ) std::cerr << std::endl;
344  //}
345  //std::cerr << std::endl << "With energy: " << ig_->get_energy_current_state_assignment();
346  //std::cerr << " and bestenergy()" << bestenergy() << std::endl;
347 
348  //clock_t stoptime = clock();
349  //std::cout << "Round " << ii << " cooling completed in " << ((double) stoptime-starttime)/CLOCKS_PER_SEC << std::endl;
350  } // end top_states
351 
352  ig_->set_network_state( best_state_on_node );
353 
354  //std::cerr << "MultiCoolAnnealer finished with an energy of " << bestenergy() << " after considering " << nsteps_ << " rotamer substitutions. " << std::endl;
355 
356  if ( ig_->any_vertex_state_unassigned() ) {
357  std::cerr << "Critical error -- In MultiCoolAnnealer, one or more vertex states unassigned at annealing's completion." << std::endl;
358  std::cerr << "Critical error -- assignment and energy of assignment meaningless" << std::endl;
359 
360  FArray1D_int nstates_for_moltenres( rotamer_sets()->nmoltenres(), 0 );
361  for (Size ii = 0; ii < num_rots_to_pack(); ++ii) {
362  ++nstates_for_moltenres( rotamer_sets()->res_for_rotamer( rot_to_pack()[ ii ] ) );
363  }
364 
365  for ( Size ii = 1, iie = rotamer_sets()->nmoltenres(); ii <= iie; ++ii) {
366  if ( best_state_on_node( ii ) == 0 ) {
367  std::cerr << "Molten res " << ii << " (residue " << rotamer_sets()->moltenres_2_resid( ii );
368  std::cerr << " ) assigned state 0 despite having " << nstates_for_moltenres( ii ) << " states to choose from" << std::endl;
369  }
370  }
371  std::cout << "num_top_kept_: " << num_top_kept_ << std::endl;
372  assert( ! ig_->any_vertex_state_unassigned() );
373  utility_exit();
374  }
375 
376  //for (int ii = 1; ii <= top_to_keep; ++ii)
377  //{
378  // for (int jj = 1; jj <= ii; ++jj )
379  // {
380  // std::cerr << " ";
381  // }
382  //
383  // for (int jj = ii + 1; jj <= top_to_keep; ++jj)
384  // {
385  // int hamming = 0;
386  // for (int kk = 1; kk <= rotamer_sets()->nmoltenres(); ++kk)
387  // {
388  // if ( top_netstates_( kk, ii ) != top_netstates_( kk, jj ) )
389  // {
390  // ++hamming;
391  // }
392  // }
393  // hamming_distance( jj, ii ) = hamming;
394  // if ( hamming < 100 ) std::cerr << " ";
395  // if ( hamming < 10 ) std::cerr << " ";
396  // std::cerr << hamming << " ";
397  // }
398  //
399  // std::cerr << energy_top_(ii) << " " << hamming_start_to_stop(ii) << " "<< second_round_cooling_finalE( ii ) << std::endl;
400  //
401  //}
402 
403  //convert best_state_on_node into best_rotamer_at_seqpos
404  for ( Size ii = 1; ii <= rotamer_sets()->nmoltenres(); ++ii) {
405  int iiresid = rotamer_sets()->moltenres_2_resid(ii);
406  bestrotamer_at_seqpos()( iiresid ) = rotamer_sets()->moltenres_rotid_2_rotid( ii, best_state_on_node(ii) );
407  }
408 }
409 
410 void
412 {
413  core::PackerEnergy temperature = get_temperature();
414  temperature = ( temperature - get_lowtemp() ) * std::exp( -1. ) + get_lowtemp();
415  set_temperature( temperature );
416 }
417 
418 void
420 (
421  FArray1D_int & state_on_node,
422  FArray1D_int & best_state_on_node,
423  core::PackerEnergy & best_energy,
424  int num_cycles
425 )
426 {
427  set_to_quench();
428  run_constant_temp_rotamer_substitutions(
429  state_on_node, best_state_on_node,
430  best_energy, num_cycles );
431  set_not_to_quench();
432 }
433 
434 void
436  FArray1D_int & state_on_node,
437  FArray1D_int & best_state_on_node,
438  core::PackerEnergy & best_energy,
439  int num_cycles
440 )
441 {
442 
443  core::PackerEnergy currentenergy = ig_->get_energy_current_state_assignment();
444  int substitutions_without_a_commit = 0;
445 
446  core::PackerEnergy threshold_for_deltaE_inaccuracy = std::sqrt( get_temperature() );
447  if ( quench() ) { threshold_for_deltaE_inaccuracy = 0; }
448  ig_->set_errorfull_deltaE_threshold( threshold_for_deltaE_inaccuracy );
449 
450  for (int n = 1; n <= num_cycles; ++n ) {
451 
452  int ranrotamer = pick_a_rotamer( n );
453  if (ranrotamer == -1) continue;
454 
455  int rotamer_seqpos = rotamer_sets()->res_for_rotamer(ranrotamer);
456  int moltenres_id = rotamer_sets()->resid_2_moltenres(rotamer_seqpos);
457  int rotamer_state_on_moltenres = rotamer_sets()->rotid_on_moltenresidue(ranrotamer);
458  int prevrotamer_state = state_on_node(moltenres_id);
459 
460  if (rotamer_state_on_moltenres == prevrotamer_state ) continue; //skip iteration
461 
462  core::PackerEnergy delta_energy, previous_energy_for_node;
463  ++nsteps_;
464  ig_->consider_substitution( moltenres_id, rotamer_state_on_moltenres,
465  delta_energy, previous_energy_for_node);
466 
467  //bk keep new rotamer if it is lower in energy or accept it at some
468  //bk probability if it is higher in energy, if it is the first
469  //bk rotamer to be tried at this position automatically accept it.
470  if ((prevrotamer_state == 0)||pass_metropolis(previous_energy_for_node,delta_energy)) {
471  substitutions_without_a_commit = 0;
472  currentenergy = ig_->commit_considered_substitution();
473  state_on_node(moltenres_id) = rotamer_state_on_moltenres;
474  if ( (prevrotamer_state == 0)||(currentenergy < best_energy) ) {
475  if ( ! ig_->any_vertex_state_unassigned() ) {
476  best_energy = currentenergy;
477  best_state_on_node = state_on_node;
478  }
479  }
480  } else {
481  ++substitutions_without_a_commit;
482  if ( quench() && (Size) substitutions_without_a_commit == 2 * num_rots_to_pack() ) {
483  //visited all rotamers without finding any that lowered the energy
484  return;
485  }
486  }// end Metropolis criteria
487 
488  if ( calc_rot_freq() && ( get_temperature() <= calc_freq_temp ) ) {
489  for ( Size ii = 1; ii <= rotamer_sets()->nmoltenres(); ++ii ) {
490  int iistate = state_on_node(ii);
491  if (iistate != 0) {
492  ++nsteps_for_rot_( rotamer_sets()->moltenres_rotid_2_rotid( ii, best_state_on_node(ii) ) );
493  }
494  }
495  }
496 
497  } //end inner iterations
498 }
499 
500 
502  FArray1D_int const & state_on_node,
503  core::PackerEnergy energy
504 )
505 {
506  if ( worst_top_energy_ != uninitialized_energy && energy > worst_top_energy_ ) return;
507  for ( Size ii = 1; ii <= rotamer_sets()->nmoltenres(); ++ii) {
508  if (state_on_node(ii) == 0 ) return;
509  }
510 
511  for ( Size ii = 1; ii <= top_to_keep; ++ii) {
512  if ( std::abs( energy - energy_top_( ii )) < 0.0001 ) {
513  bool repeat = true;
514  for ( Size jj = 1; jj <= rotamer_sets()->nmoltenres(); ++jj) {
515  if ( state_on_node( jj ) != top_netstates_( jj, ii ) ) {
516  repeat = false;
517  break;
518  }
519  }
520  if (repeat) {
521  //std::cerr << "MultiCoolAnnealer: already found this network state" << std::endl;
522  return;
523  }
524  }
525  }
526 
527  //std::cerr << "MultiCoolAnnealer: replacing worst_best: " <<
528  // which_netstate_worst_top_ << " " << worst_top_energy_ << " with " <<
529  // energy << std::endl;
530 
531  FArray1A_int netstate_to_replace(
532  top_netstates_( 1, which_netstate_worst_top_ ), rotamer_sets()->nmoltenres() );
533 
534  //keep this netstate
535  netstate_to_replace = state_on_node;
537  ++num_top_kept_;
538 
541 
542  for ( Size ii = 2; ii <= top_to_keep; ++ii ) {
546  }
547  if ( worst_top_energy_ == uninitialized_energy ) break;
548  }
549  //std::cerr << "next worst_top : " << worst_top_energy_ << " from #" << which_netstate_worst_top_ << std::endl;
550 
551 }
552 
553 } /// namespace annealer
554 } // namespace pack
555 } // namespace core