40 #include <ObjexxFCL/format.hh>
43 #include <numeric/constants.hh>
44 #include <numeric/conversions.hh>
46 #include <basic/Tracer.hh>
49 #include <utility/vector1.hh>
55 using namespace ObjexxFCL::fmt;
58 namespace optimization {
60 static basic::Tracer
TR(
"core.optimization");
74 dE_dvars.resize( min_map.
ndofs() );
89 using namespace conformation::symmetry;
92 scale = symm_info->score_multiply_factor();
118 using namespace scoring;
119 using namespace scoring::symmetry;
120 using namespace conformation::symmetry;
133 edgeit = mingraph->const_edge_list_begin(), edgeit_end = mingraph->const_edge_list_end();
134 edgeit != edgeit_end; ++edgeit ) {
144 r1_min_data, r2_min_data, pose, scorefxn.
weights(),
150 SymmetricEnergies
const & symm_energies( dynamic_cast< SymmetricEnergies const & > (pose.
energies()) );
155 edgeit = dmingraph->const_edge_list_begin(), edgeit_end = dmingraph->const_edge_list_end();
156 edgeit != edgeit_end; ++edgeit ) {
166 r1_min_data, r2_min_data, pose, scorefxn.
weights(),
172 for (
Size i=1; i<=natoms; ++i) {
178 dE_dvars[3*i-2] = F2[0]*scale;
179 dE_dvars[3*i-1] = F2[1]*scale;
180 dE_dvars[3*i ] = F2[2]*scale;
193 using namespace core;
194 using namespace core::optimization;
199 for (
Size i=1; i<=ntorsions; ++i) {
208 if( deriv == 0 )
continue;
211 AtomID id1, id2, id3, id4;
225 dE_dvars[3*atmidx1-2] += scale*(grads.get<0>().x());
226 dE_dvars[3*atmidx1-1] += scale*(grads.get<0>().y());
227 dE_dvars[3*atmidx1 ] += scale*(grads.get<0>().z());
230 dE_dvars[3*atmidx2-2] += scale*(grads.get<1>().x());
231 dE_dvars[3*atmidx2-1] += scale*(grads.get<1>().y());
232 dE_dvars[3*atmidx2 ] += scale*(grads.get<1>().z());
235 dE_dvars[3*atmidx3-2] += scale*(grads.get<2>().x());
236 dE_dvars[3*atmidx3-1] += scale*(grads.get<2>().y());
237 dE_dvars[3*atmidx3 ] += scale*(grads.get<2>().z());
240 dE_dvars[3*atmidx4-2] += scale*(grads.get<3>().x());
241 dE_dvars[3*atmidx4-1] += scale*(grads.get<3>().y());
242 dE_dvars[3*atmidx4 ] += scale*(grads.get<3>().z());
267 bool const write_to_stdout( ! deriv_check_result || deriv_check_result->send_to_stdout() );
269 Real const increment = 0.0005;
270 Size const n_increment = 1;
272 for (
Size i=1; i<= n_increment; ++i ) {
273 dE_dvars_numeric[i].resize( ndofs, 0.0 );
278 if ( deriv_check_result ) min_debug =
new NumDerivCheckData( ndofs, n_increment );
285 for (
Size i=1; i<=natoms; ++i) {
287 for (
int jj=0; jj<3; ++jj) {
288 Size ii = (i-1)*3+jj+1;
290 Real deriv_dev = 10000.0;
291 for (
Size j = 1,factor=1; j <= n_increment; ++j ) {
294 vars[ii] = start_vars[ii] + factor * increment;
295 Real const f11 = func( vars );
297 vars[ii] = start_vars[ii] - factor * increment;
298 Real const f22 = func( vars );
300 Real const deriv = ( f11 - f22 ) / ( factor * 2 * increment );
302 dE_dvars_numeric[j][ii] = deriv;
304 deriv_dev = std::min( deriv_dev, std::abs( deriv - dE_dvars[ii] ) );
306 vars[ii] = start_vars[ii];
308 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 :
309 deriv / dE_dvars[ii] );
311 if ( std::abs(dE_dvars[ii]) > 0.001 || std::abs(deriv) > 0.001 ) {
312 if ( verbose && write_to_stdout ) {
315 static bool ratio_header_output(
false );
316 if ( !ratio_header_output ) {
317 ratio_header_output =
true;
324 A( 10,
"numeric" ) <<
325 A( 10,
"analytic" ) <<
327 A( 10,
"vars[ii]" ) << std::endl;
333 I( 4, atm_id.rsd() ) <<
334 I( 4, atm_id.atomno() ) <<
335 A( 4, (jj==0)?
"x":((jj==1)?
"y":
"z") ) <<
338 F( 10, 4, dE_dvars[ii] ) <<
340 F( 10, 4, start_vars[ii] ) << std::endl;
346 Real const ratio( std::abs( dE_dvars[ii] ) < 0.001 ? 0.0 :
347 deriv_dev / std::abs( dE_dvars[ii] ) );
349 if ( min_debug ) min_debug->rel_deriv_dev( ii, ratio );
350 if ( min_debug ) min_debug->abs_deriv_dev( ii, deriv_dev );
365 for (
Size i=1; i<= ndofs; ++i ) {
366 norm += dE_dvars[i] * dE_dvars[i];
367 for (
Size j=1; j<= n_increment; ++j ) {
368 dot[j] += dE_dvars[i] * dE_dvars_numeric[j][i];
369 norm_numeric[j] += dE_dvars_numeric[j][i] * dE_dvars_numeric[j][i];
372 norm = std::sqrt( norm );
374 Real lbest_cos_theta( -10.0 );
375 Real lbest_abs_log_norm_ratio( 200.0 );
376 Real lbest_norm_analytic( 999.9 );
377 Real lbest_norm_numeric( 999.9 );
379 for (
Size j=1; j<= n_increment; ++j ) {
380 norm_numeric[j] = std::sqrt( norm_numeric[j] );
384 if ( norm < 0.001 && norm_numeric[j] < 0.001 ) {
385 log_norm_ratio = 1.0;
386 }
else if ( norm < 0.001 ) {
387 log_norm_ratio = 100.0;
388 }
else if ( norm_numeric[j] < 0.001 ) {
389 log_norm_ratio = -100.0;
391 log_norm_ratio = std::log( norm_numeric[j] / norm );
394 Real const cos_theta( dot[j] / ( norm * norm_numeric[j]) );
396 if ( write_to_stdout ) {
398 " norm: " << j <<
' ' << F(12,4,norm) <<
399 " norm_numeric: " << F(12,4,norm_numeric[j]) <<
400 " cos_theta: " << F(7,4,cos_theta) <<
401 " log_norm_ratio: " << F(9,4,log_norm_ratio) << std::endl;
404 lbest_cos_theta = std::max( lbest_cos_theta, cos_theta );
405 if ( std::abs( log_norm_ratio ) < lbest_abs_log_norm_ratio ) {
406 lbest_abs_log_norm_ratio = std::abs( log_norm_ratio );
407 lbest_norm_analytic = norm;
408 lbest_norm_numeric = norm_numeric[j];
412 if ( min_debug ) min_debug->best_cos_theta( lbest_cos_theta );
413 if ( min_debug ) min_debug->best_abs_log_norm_ratio( lbest_abs_log_norm_ratio );
414 if ( min_debug ) min_debug->best_norm_analytic( lbest_norm_analytic );
415 if ( min_debug ) min_debug->best_norm_numeric( lbest_norm_numeric );
417 if ( deriv_check_result ) deriv_check_result->add_deriv_data( min_debug );
430 core::Real inv_nrml1_mag, inv_nrml2_mag, inv_nrml3_mag;
432 core::Vector dcosdnrml1(0,0,0), dcosdnrml2(0,0,0), dsindnrml3(0,0,0), dsindnrml2(0,0,0);
433 core::Vector f(0,0,0), fi(0,0,0), fab(0,0,0), fj(0,0,0);
435 vti_vta = coords.get<0>() - coords.get<1>();
436 vta_vtb = coords.get<1>() - coords.get<2>();
437 vtb_vtj = coords.get<2>() - coords.get<3>();
439 nrml1.x() = (vti_vta.y() * vta_vtb.z() - vti_vta.z() * vta_vtb.y());
440 nrml1.y() = (vti_vta.z() * vta_vtb.x() - vti_vta.x() * vta_vtb.z());
441 nrml1.z() = (vti_vta.x() * vta_vtb.y() - vti_vta.y() * vta_vtb.x());
443 nrml2.x() = (vta_vtb.y() * vtb_vtj.z() - vta_vtb.z() * vtb_vtj.y());
444 nrml2.y() = (vta_vtb.z() * vtb_vtj.x() - vta_vtb.x() * vtb_vtj.z());
445 nrml2.z() = (vta_vtb.x() * vtb_vtj.y() - vta_vtb.y() * vtb_vtj.x());
447 nrml3.x() = (vta_vtb.y() * nrml1.z() - vta_vtb.z() * nrml1.y());
448 nrml3.y() = (vta_vtb.z() * nrml1.x() - vta_vtb.x() * nrml1.z());
449 nrml3.z() = (vta_vtb.x() * nrml1.y() - vta_vtb.y() * nrml1.x());
451 inv_nrml1_mag = 1.0 / nrml1.length();
452 inv_nrml2_mag = 1.0 / nrml2.length();
453 inv_nrml3_mag = 1.0 / nrml3.length();
455 cos_phi = (nrml1.x() * nrml2.x() + nrml1.y() * nrml2.y() + nrml1.z() * nrml2.z()) * inv_nrml1_mag * inv_nrml2_mag;
456 sin_phi = (nrml3.x() * nrml2.x() + nrml3.y() * nrml2.y() + nrml3.z() * nrml2.z()) * inv_nrml3_mag * inv_nrml2_mag;
458 nrml2.x() *= inv_nrml2_mag;
459 nrml2.y() *= inv_nrml2_mag;
460 nrml2.z() *= inv_nrml2_mag;
464 if(fabs(sin_phi) > 0.1) {
465 nrml1.x() *= inv_nrml1_mag;
466 nrml1.y() *= inv_nrml1_mag;
467 nrml1.z() *= inv_nrml1_mag;
469 dcosdnrml1.x() = inv_nrml1_mag * (nrml1.x() * cos_phi - nrml2.x());
470 dcosdnrml1.y() = inv_nrml1_mag * (nrml1.y() * cos_phi - nrml2.y());
471 dcosdnrml1.z() = inv_nrml1_mag * (nrml1.z() * cos_phi - nrml2.z());
473 dcosdnrml2.x() = inv_nrml2_mag * (nrml2.x() * cos_phi - nrml1.x());
474 dcosdnrml2.y() = inv_nrml2_mag * (nrml2.y() * cos_phi - nrml1.y());
475 dcosdnrml2.z() = inv_nrml2_mag * (nrml2.z() * cos_phi - nrml1.z());
478 nrml3.x() *= inv_nrml3_mag;
479 nrml3.y() *= inv_nrml3_mag;
480 nrml3.z() *= inv_nrml3_mag;
482 dsindnrml3.x() = inv_nrml3_mag * (nrml3.x() * sin_phi - nrml2.x());
483 dsindnrml3.y() = inv_nrml3_mag * (nrml3.y() * sin_phi - nrml2.y());
484 dsindnrml3.z() = inv_nrml3_mag * (nrml3.z() * sin_phi - nrml2.z());
486 dsindnrml2.x() = inv_nrml2_mag * (nrml2.x() * sin_phi - nrml3.x());
487 dsindnrml2.y() = inv_nrml2_mag * (nrml2.y() * sin_phi - nrml3.y());
488 dsindnrml2.z() = inv_nrml2_mag * (nrml2.z() * sin_phi - nrml3.z());
493 if(fabs(sin_phi) > 0.1) {
495 fi.x() += dE_dtor * (vta_vtb.y() * dcosdnrml1.z() - vta_vtb.z() * dcosdnrml1.y());
496 fi.y() += dE_dtor * (vta_vtb.z() * dcosdnrml1.x() - vta_vtb.x() * dcosdnrml1.z());
497 fi.z() += dE_dtor * (vta_vtb.x() * dcosdnrml1.y() - vta_vtb.y() * dcosdnrml1.x());
499 fj.x() += dE_dtor * (vta_vtb.z() * dcosdnrml2.y() - vta_vtb.y() * dcosdnrml2.z());
500 fj.y() += dE_dtor * (vta_vtb.x() * dcosdnrml2.z() - vta_vtb.z() * dcosdnrml2.x());
501 fj.z() += dE_dtor * (vta_vtb.y() * dcosdnrml2.x() - vta_vtb.x() * dcosdnrml2.y());
503 fab.x() += dE_dtor * (vti_vta.z() * dcosdnrml1.y() - vti_vta.y() * dcosdnrml1.z() + vtb_vtj.y() * dcosdnrml2.z() - vtb_vtj.z() * dcosdnrml2.y());
504 fab.y() += dE_dtor * (vti_vta.x() * dcosdnrml1.z() - vti_vta.z() * dcosdnrml1.x() + vtb_vtj.z() * dcosdnrml2.x() - vtb_vtj.x() * dcosdnrml2.z());
505 fab.z() += dE_dtor * (vti_vta.y() * dcosdnrml1.x() - vti_vta.x() * dcosdnrml1.y() + vtb_vtj.x() * dcosdnrml2.y() - vtb_vtj.y() * dcosdnrml2.x());
511 ((vta_vtb.y()*vta_vtb.y() + vta_vtb.z()*vta_vtb.z())*dsindnrml3.x()
512 - vta_vtb.x()*vta_vtb.y()*dsindnrml3.y() - vta_vtb.x()* vta_vtb.z()*dsindnrml3.z());
514 ((vta_vtb.z()*vta_vtb.z() + vta_vtb.x()*vta_vtb.x())*dsindnrml3.y()
515 - vta_vtb.y()*vta_vtb.z()*dsindnrml3.z() - vta_vtb.y()* vta_vtb.x()*dsindnrml3.x());
517 ((vta_vtb.x()*vta_vtb.x() + vta_vtb.y()*vta_vtb.y())*dsindnrml3.z()
518 - vta_vtb.z()*vta_vtb.x()*dsindnrml3.x() - vta_vtb.z()*vta_vtb.y()*dsindnrml3.y());
520 fj.x() += dE_dtor * (dsindnrml2.y() * vta_vtb.z() - dsindnrml2.z() * vta_vtb.y());
521 fj.y() += dE_dtor * (dsindnrml2.z() * vta_vtb.x() - dsindnrml2.x() * vta_vtb.z());
522 fj.z() += dE_dtor * (dsindnrml2.x() * vta_vtb.y() - dsindnrml2.y() * vta_vtb.x());
524 fab.x() += dE_dtor * (-(vta_vtb.y() * vti_vta.y() + vta_vtb.z() * vti_vta.z()) * dsindnrml3.x()
525 + (2.0 * vta_vtb.x() * vti_vta.y() - vti_vta.x() * vta_vtb.y()) * dsindnrml3.y()
526 + (2.0 * vta_vtb.x() * vti_vta.z() - vti_vta.x() * vta_vtb.z()) * dsindnrml3.z() + dsindnrml2.z() * vtb_vtj.y() - dsindnrml2.y() * vtb_vtj.z());
527 fab.y() += dE_dtor * (-(vta_vtb.z() * vti_vta.z() + vta_vtb.x() * vti_vta.x()) * dsindnrml3.y()
528 + (2.0 * vta_vtb.y() * vti_vta.z() - vti_vta.y() * vta_vtb.z()) * dsindnrml3.z()
529 + (2.0 * vta_vtb.y() * vti_vta.x() - vti_vta.y() * vta_vtb.x()) * dsindnrml3.x() + dsindnrml2.x() * vtb_vtj.z() - dsindnrml2.z() * vtb_vtj.x());
530 fab.z() += dE_dtor * (-(vta_vtb.x() * vti_vta.x() + vta_vtb.y() * vti_vta.y()) * dsindnrml3.z()
531 + (2.0 * vta_vtb.z() * vti_vta.x() - vti_vta.z() * vta_vtb.x()) * dsindnrml3.x()
532 + (2.0 * vta_vtb.z() * vti_vta.y() - vti_vta.z() * vta_vtb.y()) * dsindnrml3.y() + dsindnrml2.y() * vtb_vtj.x() - dsindnrml2.x() * vtb_vtj.y());
535 boost::get<0>(dE_dxs) = fi;
536 boost::get<1>(dE_dxs) = fab-fi;
537 boost::get<2>(dE_dxs) = fj-fab;
538 boost::get<3>(dE_dxs) = -fj;