Here are some ways to improve hbonds.cc from
OptimizingRosetta.
The energy function
The function used comes from Kortemme et al., and sums independent functions on distance and angles of the AH bond.
- Kortemme-JMB-v326-p1239.pdf: An orientation-dependent hydrogen bonding potential improves prediction of specificity and structure for proteins and protein-protein complexes, Kortemme, T., Morozov, A. V., Baker, D., J Mol Biol 326: (4) 1239-59 Feb 28 2003
- Kortemme_suppl_tables.doc: Supplementary tables
- Polynomials are used to evaluate functions of distance and angles for hbonds.
hbond_compute_energy()
Precompute unit vectors for cosine calculations
Normalized Donor-Hydrogen (DH) and Acceptor-Base (AA1) vectors are used to compute cosines for hydrogen bond energy. These can be precomputed, and only the normalized AH vector computed in the loop.
Precompute most of the bond classification
min/max cutoffs
The min/max cutoffs could depend on the type of bond. This would require classifying bonds first, however. On the other hand, the function now compares and clamps on output, which it can easily do on input.
Lower degree polynomials
Can we find lower degree polynomials with same interpolating power?
hbond_polynomial()
Include offset and scale with polynomial coefficients
There are some post-polynomial evaluations that could be pushed into the polynomial.
Jump table to unrolled polynomial evaluation
At the moment, the code computes one of 16 polynomials from coefficients in a table. Since the polynomials are of degree 2 or 7, we might unroll and inline this code, and select with a switch, which the compiler should make into a jump table.
Horner's rule
Horner's rule saves multiplications, and lets you compute polynomial and derivative at the same time. Changed
int fdegree = poly_degree(table); // offset for arrays
for ( int i = 1, l = coeff.index(i,table); i <= fdegree; ++i, ++l ) {
value += coeff[ l ] * term; // coeff(i,table)
term *= variable;
}
term = 1.0;
for ( int i = 2, l = coeff.index(i,table); i <= fdegree; ++i, ++l ) {
derivative += (i-1) * coeff[ l ] * term; // coeff(i,table)
term *= variable;
}
value -= offset(table);
int fdegree = poly_degree(table); // offset for arrays
int i = fdegree, l = coeff.index(i,table);
accum = daccum = coeff[l]; // initial value of poly & deriv;
for (i--, l--; i > 1; i--, l-- ) { // jss assume at least 2 terms
accum = coeff[l] + variable*accum; // Horner's rule
daccum = accum + variable*daccum; // " for derivs
}
accum = coeff[l] + variable*accum; // deriv stops one earlier; finish polynomial
--
JackSnoeyink - 24 Mar 2005
to top