Re: C++ Problems BIS

Posted by Luigi Ballabio-2 on
URL: http://quantlib.414.s1.nabble.com/C-Problems-BIS-tp2463p2465.html

At 11:10 AM -0500 4/11/03, Kris . wrote:
>Another idea is to use DBC
>http://www.eventhelix.com/RealtimeMantra/Object_Oriented/design_by_contract.htm
>
>You could use assertions and conditional compilations to build robust code.

Which also was my suggestion---but probably I phrased it wrongly.
I wasn't suggesting that you reimplemented log, sqrt and such adding
range checking; I merely suggested that you checked the arguments
passed to *your* functions. An example from the library:

SingleAssetOption::SingleAssetOption(Option::Type type, double underlying,
                                      double strike, Spread dividendYield,
                                      Rate riskFreeRate, Time residualTime,
                                      double volatility)
: underlying_(underlying), payoff_(type, strike),
dividendYield_(dividendYield),
   residualTime_(residualTime), hasBeenCalculated_(false),
   rhoComputed_(false), dividendRhoComputed_(false),
   vegaComputed_(false), thetaComputed_(false) {
     QL_REQUIRE(strike > 0.0,
                "SingleAssetOption::SingleAssetOption : strike ("+
                DoubleFormatter::toString(strike)+
                ") must be positive");
     QL_REQUIRE(underlying > 0.0,
                "SingleAssetOption::SingleAssetOption : underlying ("+
                DoubleFormatter::toString(underlying)+
                ") must be positive");
     QL_REQUIRE(residualTime > 0.0,
                "SingleAssetOption::SingleAssetOption : residual time ("+
                DoubleFormatter::toString(residualTime)+
                ") must be positive");
     //! Checks on volatility values are in setVolatility
     setVolatility(volatility);
     //! Checks on the risk-free rate are in setRiskFreeRate
     setRiskFreeRate(riskFreeRate);
}

The three preconditions (QL_REQUIRE) will prevent math exceptions to
occur later, for example, in:

double EuropeanOption::theta() const {
     return -underlying_ * NID1() * volatility_ *
            dividendDiscount()/(2.0*QL_SQRT(residualTime_)) +
            dividendYield_*underlying_*alpha()*dividendDiscount() -
            riskFreeRate_*payoff_.strike()*riskFreeDiscount()*beta();
}

where the square root of the residual time is taken. Moreover, and
possibly more importantly, they will greatly aid your diagnosis of
the error by telling you exactly what the problem is, and exactly at
the time when the problem is introduced---two things that _matherr
cannot do, since it has to be a generic error handling routine. In
short, it's a much robust way of coding---I'm sure the link above
will explain it better than I did.

Bye,
        Luigi