Передача функции-члена в квадратурную библиотеку C++ произвольной точности (Quadpack++)

Я пытаюсь численно интегрировать особенно неприятный класс функций, для которых изначально я использовал GSL, но ошибки округления слишком велики для моего желаемого допуска. После быстрого Google для библиотек квадратур произвольной точности я нашел quadpack++, который, кажется, делает то, что я хочу, но я не могу заставить его работать, в частности, я не могу передать функцию этой формы:

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

в качестве ввода, который он хочет в этой форме:

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() {}
};

Я новичок в С++, поэтому, вероятно, это что-то простое, но я пробовал все комбинации указателей и std::bind, которые я могу придумать, на основе Q1 и Q2 безрезультатно. Мы будем очень признательны за любую помощь в этом или предложения по лучше протестированным и задокументированным библиотекам квадратур произвольной точности.


person hbwales    schedule 10.01.2014    source источник


Ответы (1)


Прототип функции должен иметь два аргумента, а второй должен быть указателем. Я недостаточно знаю о mpf_array, чтобы понять, к чему это сводится. Если это не тип указателя, что ж, это проблема. (Кроме того, небольшое тестирование показывает, что наличие const перед параметрами не поможет.)

Возможно, что еще более важно, это должна быть бесплатная функция, и она не может принадлежать к такому классу, как MyClass (если только это не статическая функция IIRC). Вам нужны элементы MyClass внутри вашей функции?

(редактировать на основе комментария ниже). Показанный прототип функции требует (предположительно реального) типа и указателя, в основном, на все другие аргументы, для которых вам потребуется не только этот mpf_array, но и объект MyClass, который вам нужен. позвоните из. Итак, вам нужно упаковать все эти параметры вместе в одну большую... вещь.

struct helper {
    mpf_array foo;
    MyClass bob;
}

Затем мы можем создать функцию реле, которая упаковывает один из них в качестве аргументов, которые вам нужны:

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

Затем создайте вспомогательную структуру с вашим массивом fourier и вашим фактическим объектом и передайте его адрес в качестве второго параметра. Вероятно, здесь должны быть какие-то ссылки, чтобы избежать копирования, но я печатаю прямо в это поле (так что, вероятно, здесь есть и другая ошибка).

Это... в лучшем случае хакерство, но в любом случае он должен работать с этим пакетом. (Я должен признать, что не знаю ни одного пакета, который подходил бы лучше, извините.)

person tabstop    schedule 11.01.2014
comment
Спасибо, к сожалению, мне нужно ссылаться на другие элементы моего класса, поэтому я не могу легко удалить или сделать его статическим. mpf_array в основном является оболочкой вокруг std::array, а не указателем, но я могу это исправить достаточно легко. - person hbwales; 11.01.2014
comment
Кроме того, это та часть, где я признаю (ни для кого не сюрприз), что мои знания о функциях C++ 11 отрывочны или отсутствуют, поэтому, если одна из новых функций может помочь здесь, кто-то еще (надеюсь!) перезвонит в. - person tabstop; 11.01.2014
comment
Немного поздно, но для потомков: когда у меня была та же проблема, я использовал невероятно уродливый обходной путь, чтобы использовать статическую функцию-оболочку, которая получает это как параметр, который затем вызывает this.actualfunction. - person fifaltra; 06.05.2014