странное поведение функции повышения - PullRequest
0 голосов
/ 03 июля 2018

Мой следующий код работает с ошибкой, если я закомментирую первую строку в конструкторе. Ошибка возврата:

libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::overflow_error> >: Error in function boost::math::cyl_bessel_k<double>(double,double): numeric overflow
Abort trap: 6

Однако странно, что если я что-то выводю (например, раскомментирую первую строку) в конструкторе, тогда моя программа работает нормально.

GP::GP(const Training_set& _sample, Eigen::VectorXd& param, 
                const std::string& which_kernel) : sample(_sample)
{
//      std::cout << "WORKS" << std::endl;
        if (which_kernel == "Matern") {
                std::cout << "Matern kernel is used!" << std::endl;
                Kernel_Matern matern(param, param.size());
                kernel = &matern;
        } else if (which_kernel == "Square_Exponential") {
                std::cout << "Square Exponential kernel is used!" << std::endl;
                Kernel_SE se(param, param.size());
                kernel = &se;
        } else {
                std::cout << "Cannot identify the kernel" << std::endl;
                exit(1);
        }   
        input_dim = sample.dim;
        input_size = sample.size;
        L_chol.resize(sample.size, sample.size);
        Eigen::MatrixXd cov_matrix = Eigen::MatrixXd::Zero(sample.size, sample.size);
        get_cov_matrix(sample.X, input_size, sample.X, input_size, cov_matrix);
        get_chol(cov_matrix);
}

1 Ответ

0 голосов
/ 03 июля 2018

Вы храните адрес временного, который выходит за рамки. Использование *kernel после того, что указывает на то, что выходит из области видимости, является неопределенным поведением.

kernel должен иметь тип std::unique_ptr<X> вместо типа X*.

Заменить назначение на:

 kernel = std::make_unique<Kernel_Matern>(param, param.size());

или

 kernel = std::make_unique<Kernel_SE>(param, param.size());

в двух рассматриваемых строках.

Если у вас есть код, в котором вы передаете kernel функции, вместо этого передайте kernel.get().

Обратите внимание, что блоки копируют экземпляры GP, но не перемещают их, поскольку уникальный ptr предназначен только для перемещения. Если у вас есть тип, который хранит значения и указатели в своих собственных значениях, его копирование, вероятно, в любом случае будет ошибкой.

...