Трудно получить barycentric_rational от библиотеки повышения c ++, чтобы работать так, как мне нужно - PullRequest
0 голосов
/ 24 января 2019

Я использую barycentric_rational из библиотеки C ++ Boost для интерполяции данных, хранящихся в векторах. Векторы заполняются внутри класса, и мне нужно выполнить интерполяцию после заполнения векторов, чтобы я мог написать функцию доступа, чтобы получить интерполированное значение в определенной точке. Примерно так:

class V{
public:
    V(/* some arguments */){

        //populate x and y

        b=barycentric_rational<double>(x.data(),y.data(),x.size());
    }

    double psi(double r){
         return b(r);
    }

private:
   std::vector<double> x,y;
   barycentric_rational<double> b;  
};

Я получаю сообщение об ошибке:

error: no matching function for call to    ‘boost::math::barycentric_rational<double>::barycentric_rational()

Я думаю, что получаю это сообщение, потому что b нужно инициализировать в списке инициализаторов, но код для заполнения x и y в моем приложении сложен. Установка x и y в отдельном публичном методе не работает по той же причине.

Я пробовал следующее решение:

class V{
public:
    V(/* some arguments */):b(nullptr){

        //populate x and y

        b=new barycentric_rational<double>(x.data(),y.data(),x.size());
    }

    ~V(){
          delete b;
     }

    double psi(double r){
         return b->operator()(r);
    }

private:
   std::vector<double> x,y;
   barycentric_rational<double> *b; 
};

, который, кажется, работает. Однако мне это не нравится по двум причинам: а) я использую необработанные указатели, и в конце концов мне нужно иметь возможность использовать операторы копирования и присваивания, которые могут вызвать у меня проблемы, и б) я уверен, что должно быть аккуратный способ сделать это.

Пожалуйста, кто-нибудь может предложить способ сделать то, что мне нужно?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Другое решение - просто инициализировать b с пустыми x и y, а затем присвоить ему другое правильное значение:

V(/* some arguments */) : b(x.data(),y.data(),x.size()){
    //populate x and y
    b=barycentric_rational<double>(x.data(),y.data(),x.size());
}
0 голосов
/ 24 января 2019

Вы можете просто инициировать его в списке инициализации. Если вам нужно использовать некоторую специальную логику для заполнения x и y, вы можете сделать это отдельным методом.

class V{
public:
    V(/* some arguments */)
    : x(populateX()),  y(populateY()), b(x.data(),y.data(),x.size())
    {
    }

    std::vector<double> populateX() {
    }
    std::vector<double> populateY() {
    }

    double psi(double r){
         return b(r);
    }

private:
   std::vector<double> x,y;
   barycentric_rational<double> b;  
};

Если код, который заполняет x и y, слишком сложен, и инициализация x и y не может быть выполнена отдельно, тогда вы можете переместить его в отдельный класс:

struct XY {
    XY(/* some args */) {
        //init x and y
    }
    std::vector<double> x;
    std::vector<double> y;
};
class V{
public:
    V(/* some arguments */)
    : xy(/*some args */), b(xy.x.data(),xy.y.data(),xy.x.size())
    {
    }

    double psi(double r){
         return b(r);
    }

private:
   XY xy;
   barycentric_rational<double> b;  
};
...