Changing the Policy on an Ad Hoc Basis for the Special Functions

| Home | Libraries | People | FAQ | More

#### Changing the Policy on an Ad Hoc Basis for the Special Functions

All of the special functions in this library come in two overloaded forms, one with a final "policy" parameter, and one without. For example:

    namespace boost{ namespace math{

    template <class RealType, class Policy>
    RealType tgamma(RealType, const Policy&);

    template <class RealType>
    RealType tgamma(RealType);

    }} // namespaces

Normally, the second version is just a forwarding wrapper to the first like this:

    template <class RealType>
    inline RealType tgamma(RealType x)
    {
       return tgamma(x, policies::policy<>());
    }

So calling a special function with a specific policy is just a matter of defining the policy type to use and passing it as the final parameter. For example, suppose we want `tgamma` to behave in a C-compatible fashion and set `::errno` when an error occurs, and never throw an exception:

    #include <boost/math/special_functions/gamma.hpp>
    using boost::math::tgamma;

    // Define the policy to use:
    using namespace boost::math::policies; // may be convenient, or

    using boost::math::policies::policy;
    // Types of error whose action can be altered by policies:.
    using boost::math::policies::evaluation_error;
    using boost::math::policies::domain_error;
    using boost::math::policies::overflow_error;
    using boost::math::policies::domain_error;
    using boost::math::policies::pole_error;
    // Actions on error (in enum error_policy_type):
    using boost::math::policies::errno_on_error;
    using boost::math::policies::ignore_error;
    using boost::math::policies::throw_on_error;
    using boost::math::policies::user_error;

    typedef policy<
       domain_error<errno_on_error>,
       pole_error<errno_on_error>,
       overflow_error<errno_on_error>,
       evaluation_error<errno_on_error>
    > c_policy;
    //
    // Now use the policy when calling tgamma:

    // http://msdn.microsoft.com/en-us/library/t3ayayh1.aspx
    // Microsoft errno declared in STDLIB.H as "extern int errno;"

    int main()
    {
       errno = 0; // Reset.
       cout << "Result of tgamma(30000) is: "
          << tgamma(30000, c_policy()) << endl; // Too big parameter
       cout << "errno = " << errno << endl; // errno 34 Numerical result out of range.
       cout << "Result of tgamma(-10) is: "
          << boost::math::tgamma(-10, c_policy()) << endl; // Negative parameter.
       cout << "errno = " << errno << endl; // error 33 Numerical argument out of domain.
    } // int main()

which outputs:

    Result of tgamma(30000) is: 1.#INF
    errno = 34
    Result of tgamma(-10) is: 1.#QNAN
    errno = 33

Alternatively, for ad hoc use, we can use the `make_policy` helper function to create a policy for us: this usage is more verbose, so is probably only preferred when a policy is going to be used once only:

    #include <boost/math/special_functions/gamma.hpp>
    using boost::math::tgamma;

    int main()
    {
       // using namespace boost::math::policies; // or
       using boost::math::policies::errno_on_error;
       using boost::math::policies::make_policy;
       using boost::math::policies::pole_error;
       using boost::math::policies::domain_error;
       using boost::math::policies::overflow_error;
       using boost::math::policies::evaluation_error;

       errno = 0;
       std::cout << "Result of tgamma(30000) is: "
          << boost::math::tgamma(
             30000,
             make_policy(
                domain_error<errno_on_error>(),
                pole_error<errno_on_error>(),
                overflow_error<errno_on_error>(),
                evaluation_error<errno_on_error>()
             )
          ) << std::endl;
       // Check errno was set:
       std::cout << "errno = " << errno << std::endl;
       // and again with evaluation at a pole:
       std::cout << "Result of tgamma(-10) is: "
          << boost::math::tgamma(
             -10,
             make_policy(
                domain_error<errno_on_error>(),
                pole_error<errno_on_error>(),
                overflow_error<errno_on_error>(),
                evaluation_error<errno_on_error>()
             )
          ) << std::endl;
       // Check errno was set:
       std::cout << "errno = " << errno << std::endl;
    }