41 #include <ObjexxFCL/format.hh>
45 #include <numeric/constants.hh>
59 #include <basic/Tracer.hh>
63 #include <utility/vector1.hh>
69 using namespace ObjexxFCL::fmt;
72 namespace optimization {
74 static basic::Tracer
TR(
"core.optimization");
133 dE_dvars.resize( min_map.
nangles() );
171 it != ite; ++it, ++imap ) {
197 Real torsion_scale_factor
226 if ( type ==
PHI || type ==
THETA || type ==
RB4 || type ==
RB5 ||
231 Real scale_factor( ( type ==
PHI || type ==
THETA ) ? 1 : numeric::constants::d::deg2rad );
233 if ( type ==
THETA ) {
235 using numeric::constants::f::pi;
236 Real const theta( atom.
dof( type ) );
238 ( ( static_cast< int >( std::floor( theta/pi )))%2);
239 if ( theta_mod == 1 || theta_mod == -1 ) {
240 scale_factor *= -1.0f;
244 deriv -= scale_factor * ( dot( axis, dof_node.
F1() ) +
245 dot( cross( axis, end_pos ), dof_node.
F2() ) );
248 deriv += dot( axis, dof_node.
F2() );
253 deriv /= torsion_scale_factor;
270 using namespace scoring;
283 edgeit = mingraph->const_edge_list_begin(), edgeit_end = mingraph->const_edge_list_end();
284 edgeit != edgeit_end; ++edgeit ) {
294 r1_min_data, r2_min_data, pose, scorefxn.
weights(),
299 iter != iter_e; ++iter ) {
303 for ( DOF_Node::AtomIDs::const_iterator it1=dof_node.
atoms().begin(),
304 it1e = dof_node.
atoms().end(); it1 != it1e; ++it1 ) {
314 SimpleDerivCheckResult
342 Size const nangles( start_vars.size() );
345 Real const increment = 0.0005;
346 Size const n_increment = nsteps;
351 for (
Size i=1; i<= n_increment; ++i ) {
352 dE_dvars_numeric[i].resize( nangles, 0.0 );
358 Real const f00 = func( vars );
360 for (
Size ii = 1; ii <= vars.size(); ++ii ) {
361 Real deriv_dev = 10000.0;
362 for (
Size j = 1,factor=1; j <= n_increment; ++j ) {
365 vars[ii] = start_vars[ii] + factor * increment;
366 Real const f11 = func( vars );
372 vars[ii] = start_vars[ii] - factor * increment;
373 Real const f22 = func( vars );
380 Real const deriv = ( f11 - f22 ) / ( factor * 2 * increment );
384 dE_dvars_numeric[j][ii] = deriv;
386 deriv_dev = std::min( deriv_dev, std::abs( deriv - dE_dvars[ii] ) );
388 vars[ii] = start_vars[ii];
390 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 : deriv / dE_dvars[ii] );
392 if ( std::abs(dE_dvars[ii]) > 0.001 || std::abs(deriv) > 0.001 ) {
396 if ( verbose && send_to_stdout ) {
399 static bool ratio_header_output(
false );
400 if ( !ratio_header_output ) {
401 ratio_header_output =
true;
404 A( 10,
"numeric" ) <<
405 A( 10,
"analytic" ) <<
410 A( 10,
"vars[ii]" ) << std::endl;
416 F( 10, 4, dE_dvars[ii] ) <<
421 F( 10, 4, start_vars[ii] ) << std::endl;
428 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 :
429 deriv_dev / std::abs( dE_dvars[ii] ) );
434 if ( verbose && send_to_stdout ) {
437 TR <<
"deriv_dev:" << SS(ii) << SS(nangles) << SS(f00) <<
438 SS( dE_dvars[ii] ) << SS( deriv_dev ) << SS(ratio) << std::endl;
446 for (
Size i=1; i<= nangles; ++i ) {
447 norm += dE_dvars[i] * dE_dvars[i];
448 for (
Size j=1; j<= n_increment; ++j ) {
449 dot[j] += dE_dvars[i] * dE_dvars_numeric[j][i];
450 norm_numeric[j] += dE_dvars_numeric[j][i] * dE_dvars_numeric[j][i];
453 norm = std::sqrt( norm );
455 Real const too_small( 0.0001 );
462 for (
Size j=1; j<= n_increment; ++j ) {
463 norm_numeric[j] = std::sqrt( norm_numeric[j] );
467 if ( norm < too_small && norm_numeric[j] < too_small ) {
468 log_norm_ratio = 1.0;
469 }
else if ( norm < 0.125 * too_small ) {
470 log_norm_ratio = 100.0;
471 }
else if ( norm_numeric[j] < 0.125 * too_small ) {
472 log_norm_ratio = -100.0;
474 log_norm_ratio = std::log( norm_numeric[j] / norm );
477 Real const cos_theta( dot[j] / ( norm * norm_numeric[j]) );
479 if ( send_to_stdout ) {
481 " norm: " << j <<
' ' << F(12,4,norm) <<
482 " norm_numeric: " << F(12,4,norm_numeric[j]) <<
483 " cos_theta: " << F(7,4,cos_theta) <<
484 " log_norm_ratio: " << F(9,4,log_norm_ratio) << std::endl;
494 if ( send_to_stdout ) {
501 return num_deriv_result;
535 bool const write_to_stdout( ! deriv_check_result || deriv_check_result->send_to_stdout() );
537 Real const increment = 0.0005;
538 Size const n_increment = 5;
540 for (
Size i=1; i<= n_increment; ++i ) {
541 dE_dvars_numeric[i].resize( nangles, 0.0 );
547 if ( deriv_check_result ) min_debug =
new NumDerivCheckData( nangles, n_increment );
557 Real const f00 = func( vars );
561 iter_end= min_map.
end(); iter != iter_end; ++iter, ++ii ) {
562 DOF_Node const & dof_node( **iter );
564 Real deriv_dev = 10000.0;
565 for (
Size j = 1,factor=1; j <= n_increment; ++j ) {
568 vars[ii] = start_vars[ii] + factor * increment;
569 Real const f11 = func( vars );
571 vars[ii] = start_vars[ii] - factor * increment;
572 Real const f22 = func( vars );
574 Real const deriv = ( f11 - f22 ) / ( factor * 2 * increment );
576 dE_dvars_numeric[j][ii] = deriv;
578 deriv_dev = std::min( deriv_dev, std::abs( deriv - dE_dvars[ii] ) );
580 vars[ii] = start_vars[ii];
582 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 :
583 deriv / dE_dvars[ii] );
585 if ( std::abs(dE_dvars[ii]) > 0.001 || std::abs(deriv) > 0.001 ) {
587 if ( dof_node.
parent() ) {
588 parent_id = dof_node.
parent()->dof_id();
591 deriv, dE_dvars[ii], ratio, f11, f00, f22, start_vars[ ii ] );
592 if ( min_debug ) min_debug->dof_step_data( ii, j, dp );
593 if ( verbose && write_to_stdout ) {
596 static bool ratio_header_output(
false );
597 if ( !ratio_header_output ) {
598 ratio_header_output =
true;
608 A( 10,
"numeric" ) <<
609 A( 10,
"analytic" ) <<
614 A( 10,
"vars[ii]" ) << std::endl;
620 I( 4, dof_node.
rsd() ) <<
621 I( 4, dof_node.
type() ) <<
622 I( 4, dof_node.
atomno() ) <<
623 I( 5, parent_id.
rsd() ) <<
624 I( 5, parent_id.
type() ) <<
625 I( 5, parent_id.
atomno() ) <<
626 I( 5, dof_node.
atoms().size()) <<
628 F( 10, 4, dE_dvars[ii] ) <<
633 F( 10, 4, start_vars[ii] ) << std::endl;
640 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 :
641 deriv_dev / std::abs( dE_dvars[ii] ) );
643 if ( min_debug ) min_debug->rel_deriv_dev( ii, ratio );
644 if ( min_debug ) min_debug->abs_deriv_dev( ii, deriv_dev );
646 if ( verbose && write_to_stdout ) {
649 TR <<
"deriv_dev:" << SS(ii) << SS(nangles) << SS(f00) <<
650 SS( dof_node.
type() ) << SS( dof_node.
atomno() ) <<
651 SS( dof_node.
rsd() ) <<
652 SS( dE_dvars[ii] ) << SS( deriv_dev ) << SS(ratio) << std::endl;
660 for (
Size i=1; i<= nangles; ++i ) {
661 norm += dE_dvars[i] * dE_dvars[i];
662 for (
Size j=1; j<= n_increment; ++j ) {
663 dot[j] += dE_dvars[i] * dE_dvars_numeric[j][i];
664 norm_numeric[j] += dE_dvars_numeric[j][i] * dE_dvars_numeric[j][i];
667 norm = std::sqrt( norm );
669 Real lbest_cos_theta( -10.0 );
670 Real lbest_abs_log_norm_ratio( 200.0 );
671 Real lbest_norm_analytic( 999.9 );
672 Real lbest_norm_numeric( 999.9 );
674 for (
Size j=1; j<= n_increment; ++j ) {
675 norm_numeric[j] = std::sqrt( norm_numeric[j] );
679 if ( norm < 0.001 && norm_numeric[j] < 0.001 ) {
680 log_norm_ratio = 1.0;
681 }
else if ( norm < 0.001 ) {
682 log_norm_ratio = 100.0;
683 }
else if ( norm_numeric[j] < 0.001 ) {
684 log_norm_ratio = -100.0;
686 log_norm_ratio = std::log( norm_numeric[j] / norm );
689 Real const cos_theta( dot[j] / ( norm * norm_numeric[j]) );
691 if ( write_to_stdout ) {
693 " norm: " << j <<
' ' << F(12,4,norm) <<
694 " norm_numeric: " << F(12,4,norm_numeric[j]) <<
695 " cos_theta: " << F(7,4,cos_theta) <<
696 " log_norm_ratio: " << F(9,4,log_norm_ratio) << std::endl;
699 lbest_cos_theta = std::max( lbest_cos_theta, cos_theta );
700 if ( std::abs( log_norm_ratio ) < lbest_abs_log_norm_ratio ) {
701 lbest_abs_log_norm_ratio = std::abs( log_norm_ratio );
702 lbest_norm_analytic = norm;
703 lbest_norm_numeric = norm_numeric[j];
707 if ( min_debug ) min_debug->best_cos_theta( lbest_cos_theta );
708 if ( min_debug ) min_debug->best_abs_log_norm_ratio( lbest_abs_log_norm_ratio );
709 if ( min_debug ) min_debug->best_norm_analytic( lbest_norm_analytic );
710 if ( min_debug ) min_debug->best_norm_numeric( lbest_norm_numeric );
712 if ( deriv_check_result ) deriv_check_result->add_deriv_data( min_debug );