Skip to content

Commit

Permalink
Avoid test failure with VC++14.
Browse files Browse the repository at this point in the history
The compiler inlined std::min and std::max incorrectly,
causing calculations to fail.

Closes lballabio#130.
  • Loading branch information
lballabio committed Sep 16, 2016
1 parent d449965 commit 9618244
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions ql/math/ode/adaptiverungekutta.hpp
Expand Up @@ -180,7 +180,7 @@ namespace QuantLib {
Real& hnext,
const OdeFct& derivs) {
Size n=y.size();
Real errmax,htemp,xnew;
Real errmax,xnew;
std::vector<T> yerr(n),ytemp(n);

Real h=htry;
Expand All @@ -192,12 +192,20 @@ namespace QuantLib {
errmax=std::max(errmax,std::abs(yerr[i]/yScale[i]));
errmax/=eps;
if (errmax>1.0) {
htemp=ADAPTIVERK_SAFETY*h*std::pow(errmax,ADAPTIVERK_PSHRINK);
h = (h>=0.0 ? std::max(htemp,h/10) : std::min(htemp,h/10));
Real htemp1 = ADAPTIVERK_SAFETY*h*std::pow(errmax,ADAPTIVERK_PSHRINK);
Real htemp2 = h / 10;
// These would be std::min and std::max, of course,
// but VC++14 had problems inlining them and caused
// the wrong results to be calculated. The problem
// seems to be fixed in update 3, but let's keep this
// implementation for compatibility.
Real max_positive = htemp1 > htemp2 ? htemp1 : htemp2;
Real max_negative = htemp1 < htemp2 ? htemp1 : htemp2;
h = ((h >= 0.0) ? max_positive : max_negative);
xnew=x+h;
if (xnew==x)
QL_FAIL("Stepsize (" << xnew
<< ") underflow in AdaptiveRungeKutta::rkqs");
QL_FAIL("Stepsize underflow (" << h << " at x = " << x
<< ") in AdaptiveRungeKutta::rkqs");
continue;
} else {
if (errmax>ADAPTIVERK_ERRCON)
Expand Down

0 comments on commit 9618244

Please sign in to comment.