2

I'm trying to to numerically integrate a particularly nasty class of functions, for which initially i was using GSL, but the round off errors are too large for my desired tolerance. After a quick Google for arbitrary precision quadrature libraries i found quadpack++, which appears to do what i want, but i can't make it work, specifically i can't seem to pass a function of this form:

mpf MyClass::foo( mpf t, const mpf_array& fourier ){   
    // do stuf
}

as an input, which it wants in this form:

template<typename Real, class param_t>
    class Function : public FtnBase<Real> {
public:
    typedef Real defn_t(Real, param_t*);    
    defn_t& function_;
    param_t* params_;

    virtual Real operator() (Real x) {return function_(x, params_); }
    Function(defn_t& function) : function_(function), params_(0) {}
    Function(defn_t& function, param_t* params) : function_(function), params_(params) {}               
    ~Function() {}
};

I am pretty new to C++ so it's probably something simple but i have tried every combination of pointers and std::bind i can think of based on Q1 and Q2 to no avail. Any help with this, or suggestions for better tested & documented arbitrary precision quadrature libraries would be greatly appreciated.

Community
  • 1
  • 1
hbwales
  • 23
  • 2

1 Answers1

1

The function prototype has to have two arguments, and the second one has to be a pointer. I don't know enough about mpf_array to know what it boils down to. If it's not a pointer type, well, that's a problem. (Also a bit of testing shows that having const in front of the params is not going to help.)

Probably more importantly though, it has to be a free function, and can't belong to a class like MyClass (unless it's a static function IIRC). Do you need elements of MyClass inside your function?

(edit based on comment below). The function prototype shown requires a (presumably real) type and a pointer to, basically, all the other arguments, which for you is going to require not only this mpf_array thing but also the MyClass object you need to call it from. So you need to package all those params together into one big ... thing.

struct helper {
    mpf_array foo;
    MyClass bob;
}

Then we can make a relay function that packages one of these up as the arguments that you need:

mpf relay(mpf t, helper* args) {
    return args->bob.actual_function(t, args->foo);
}

Then create a helper struct with your fourier array and your actual object and pass its address as the second param. There should probably be some references in here to avoid copying, but I'm typing straight into this box (so there's probably some other error in here too).

This is ... hackish at best, but it should get the job done with this package anyway. (I have to admit I don't know of any package that would suit better, sorry.)

tabstop
  • 1,743
  • 10
  • 10
  • Thanks, sadly I do need to reference other elements of my class, so I cant easily take it out or make it static. `mpf_array` is basically a wrapper around std::array, and not a pointer, but i can fix that easily enough. – hbwales Jan 11 '14 at 00:18
  • Also, this is the part where I acknowledge (to no one's surprise) that my knowledge of C++11 features is spotty-to-nonexistent, so if one of the new features can help here, someone else will (hopefully!) chime in. – tabstop Jan 11 '14 at 00:41
  • Bit late, but for posterity: When I had the same problem I used the incredibly ugly workaround to use a static wrapper function, which receives "this" as a parameter, which then calls this.actualfunction. – fifaltra May 06 '14 at 01:21