Boost logo

Boost Users :

From: Warren Weckesser (warren.weckesser_at_[hidden])
Date: 2022-04-13 16:15:12


I am wrapping some boost special functions as NumPy "ufuncs" for
the Python library SciPy, and I am setting a policy to control
how errors are handled. For example, the wrapper of erf_inv
(for C++ types float, double and long double) is wrapped as the
function scipy.special.erfinv (i.e. the Python function is
erfinv in the module scipy.special).

The actual core instantiation of the function for type, say, double,
in C++ that is called by the ufunc implementation is

    double erfinv_double(double x)
    {
        return erf_inv(x, special_policy());
    }

where erf_inv is the Boost function, and special_policy is
created as

    template <class T>
    T user_domain_error(const char *function, const char * message,
const T& val)
    {
        sf_error("erfinv", SF_ERROR_DOMAIN, NULL);
        return std::numeric_limits<T>::quiet_NaN();
    }

    typedef policy<
        domain_error<user_error>,
        overflow_error<ignore_error>
> special_policy;

Note that the error handler is calling sf_error(), a function in
the SciPy special library. The first argument is the name of the
SciPy Python function. That function might generate a Python
warning or set a Python exception, and the name displayed in the
error message should be the name of the SciPy function, and not
something like "boost::math::erf_inv[...]".

This leads to the problem. The above code, with a hard-coded string
"erfinv" passed to sf_error(), works for erfinv, but obviously I
can't use the same implementation of user_domain_error for a wrapper
of, say, tgamma_ratio.

So the question is, can different policies be created that have
different user-defined error handlers? Or is there a clever way
to get the SciPy name into the user_domain_error() function?
(I hope there is something simple--I am not a C++ guru, so I
may have missed something obvious.)

I am considering creating a mapping from some parsed version of the
function argument of user_domain_error to the SciPy names. E.g. the
function argument could be scanned for the occurrence of "erf_inv",
and know that the name "erfinv" should be passed to sf_error(). A
table of regex patterns with corresponding SciPy names might do the
trick. But I'm wondering if there is a more elegant (and more
maintainable) solution.

Regards,

Warren


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net