CGAL фильтрованное ядро ​​без ленивых вычислений

Я изучал CGAL, и у меня возникли проблемы при попытке определить ядро, которое удовлетворяет тому, что мне нужно.

Мне нужно ядро, которое является потокобезопасным, но в то же время я хочу хранить точные координаты.

Если я правильно понял документацию CGAL:

  • Параметр correct_predicates_inexact_constructions_kernel является поточно-ориентированным, но в нем хранятся координаты в виде двойных значений.
  • Точное_predicates_exact_constructions_kernel хранит точные координаты, но не является потокобезопасным (из-за типа ленивых чисел).
  • CGAL:: Simple_cartesian является потокобезопасным и точно хранит координаты. Тем не менее, это намного медленнее для моего приложения.

Я в основном пришел к выводу, что мне нужно что-то вроде:

CGAL::Filtered_kernel<CGAL::Simple_cartesian<mpq_class>>

(ядро, которое использует отфильтрованную интервальную арифметику для производительности, хранит точные координаты (которые будут использоваться при сбое фильтра) и не использует ленивый тип чисел).

Я думаю, что это ядро ​​будет работать медленнее, чем current_predicates_exact_constructions_kernel, но оно будет поточно-ориентированным и намного быстрее, чем нефильтрованное ядро. (кроме того, я думаю, что ленивые типы чисел не были бы так полезны для моего приложения, потому что я все равно хочу вывести точные координаты и, таким образом, они должны быть вычислены в какой-то момент - то есть единственная "оптимизация", которая мне нужна это быстро фильтруемые предикаты)

Проблема в том, что я пытался скомпилировать тестовое приложение с этим ядром, и компиляция всегда дает сбой. Есть ли причина, по которой я не могу создать отфильтрованное ядро, которое хранит не только интервалы с плавающей точкой, но и точные координаты?

PS: я использую CGAL 4.10 на Linux

Спасибо!


Обновление: минимальный пример, который терпит неудачу:

#include <CGAL/gmpxx.h> //needed to use mpq_class as the field type
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Filtered_kernel.h> 
#include <CGAL/Lazy_kernel.h> 

//typedef CGAL::Exact_predicates_exact_constructions_kernel   Kernel; //works...
//typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<double>> Kernel; //works...
//typedef CGAL::Simple_cartesian<mpq_class> Kernel; //works!
//typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<CGAL::Gmpq>> Kernel; //works! (but Gmpq is not thread safe, while mpq_class is)
typedef CGAL::Filtered_kernel<CGAL::Simple_cartesian<mpq_class>> Kernel;
typedef Kernel::Point_3                                       Point_3;

int main() {
    Point_3 a(0,0,0);
    Point_3 b(1,0,0);
    Point_3 c(0,1,0);
    Point_3 d(1,1,1);

    //The code compiles if I remove the line below
    CGAL::Orientation orientationP0Triangle = CGAL::orientation(a,b,c,d);
}

Сообщение об ошибке:

In file included from /usr/local/include/CGAL/Cartesian_converter.h:35:0,
                 from /usr/local/include/CGAL/Filtered_kernel.h:27,
                 from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:29,
                 from cgalSimpleExample.cpp:2:
/usr/local/include/CGAL/NT_converter.h: In instantiation of ‘NT2 CGAL::NT_converter<NT1, NT2>::operator()(const NT1&) const [with NT1 = __gmp_expr<__mpq_struct [1], __mpq_struct [1]>; NT2 = CGAL::Gmpq]’:
/usr/local/include/CGAL/Cartesian_converter.h:293:45:   required from ‘typename K2::Point_3 CGAL::Cartesian_converter<K1, K2, Converter>::operator()(const typename K1::Point_3&) const [with K1 = CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >; K2 = CGAL::Simple_cartesian<CGAL::Gmpq>; Converter = CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Gmpq>; typename K2::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; typename K1::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Filtered_predicate.h:175:27:   required from ‘CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::result_type CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::operator()(const Args& ...) const [with Args = {CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >, CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> >, true> >}; EP = CGAL::CartesianKernelFunctors::Orientation_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; AP = CGAL::CartesianKernelFunctors::Orientation_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; C2E = CGAL::Cartesian_converter<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Simple_cartesian<CGAL::Gmpq>, CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Gmpq> >; C2A = CGAL::Cartesian_converter<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Simple_cartesian<CGAL::Interval_nt<false> >, CGAL::NT_converter<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Interval_nt<false> > >; bool Protection = true; CGAL::Filtered_predicate<EP, AP, C2E, C2A, Protection>::result_type = CGAL::Sign]’
/usr/local/include/CGAL/internal/Static_filters/Orientation_3.h:170:41:   required from ‘CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::result_type CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::operator()(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const [with K_base = CGAL::Filtered_kernel_base<CGAL::Type_equality_wrapper<CGAL::Cartesian_base_no_ref_count<__gmp_expr<__mpq_struct [1], __mpq_struct [1]>, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >, CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > > >; CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::result_type = CGAL::Sign; CGAL::internal::Static_filters_predicates::Orientation_3<K_base>::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Kernel/global_functions_internal_3.h:860:45:   required from ‘typename K::Orientation CGAL::internal::orientation(const typename K::Point_3&, const typename K::Point_3&, const typename K::Point_3&, const typename K::Point_3&, const K&) [with K = CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > >; typename K::Orientation = CGAL::Sign; typename K::Point_3 = CGAL::Point_3<CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > > >]’
/usr/local/include/CGAL/Kernel/global_functions_3.h:1047:47:   required from ‘typename K::Orientation CGAL::orientation(const CGAL::Point_3<R>&, const CGAL::Point_3<R>&, const CGAL::Point_3<R>&, const CGAL::Point_3<R>&) [with K = CGAL::Filtered_kernel<CGAL::Simple_cartesian<__gmp_expr<__mpq_struct [1], __mpq_struct [1]> > >; typename K::Orientation = CGAL::Sign]’
cgalSimpleExample.cpp:19:69:   required from here
/usr/local/include/CGAL/NT_converter.h:41:21: error: no matching function for call to ‘CGAL::Gmpq::Gmpq(const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>&)’
         return NT2(a);
                     ^
/usr/local/include/CGAL/NT_converter.h:41:21: note: candidates are:
In file included from /usr/local/include/CGAL/Gmp_coercion_traits.h:33:0,
                 from /usr/local/include/CGAL/Gmpz.h:33,
                 from /usr/local/include/CGAL/internal/Exact_type_selector.h:36,
                 from /usr/local/include/CGAL/Filtered_kernel.h:35,
                 from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:29,
                 from cgalSimpleExample.cpp:2:
/usr/local/include/CGAL/GMP/Gmpq_type.h:193:3: note: CGAL::Gmpq::Gmpq(const string&, int)
   Gmpq(const std::string& str, int base = 10)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:193:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const string& {aka const std::basic_string<char>&}’
/usr/local/include/CGAL/GMP/Gmpq_type.h:174:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpfr&)
   Gmpq(const Gmpfr &f)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:174:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpfr&’
/usr/local/include/CGAL/GMP/Gmpq_type.h:168:3: note: CGAL::Gmpq::Gmpq(double)
   Gmpq(double d)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:168:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘double’
/usr/local/include/CGAL/GMP/Gmpq_type.h:161:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpz&, const CGAL::Gmpz&)
   Gmpq(const Gmpz& n, const Gmpz& d)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:161:3: note:   candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:155:3: note: CGAL::Gmpq::Gmpq(long unsigned int, long unsigned int)
   Gmpq(unsigned long n, unsigned long d)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:155:3: note:   candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:149:3: note: CGAL::Gmpq::Gmpq(long int, long unsigned int)
   Gmpq(signed long n, unsigned long d)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:149:3: note:   candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:139:3: note: CGAL::Gmpq::Gmpq(int, int)
   Gmpq(int n, int d)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:139:3: note:   candidate expects 2 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:136:3: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpz&)
   Gmpq(const Gmpz& n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:136:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpz&’
/usr/local/include/CGAL/GMP/Gmpq_type.h:124:3: note: CGAL::Gmpq::Gmpq(long long int)
   Gmpq(long long n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:124:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long long int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:116:3: note: CGAL::Gmpq::Gmpq(long long unsigned int)
   Gmpq(unsigned long long n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:116:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long long unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:104:3: note: CGAL::Gmpq::Gmpq(long unsigned int)
   Gmpq(unsigned long n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:104:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:101:3: note: CGAL::Gmpq::Gmpq(long int)
   Gmpq(long n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:101:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘long int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:98:3: note: CGAL::Gmpq::Gmpq(unsigned int)
   Gmpq(unsigned int n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:98:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘unsigned int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:95:3: note: CGAL::Gmpq::Gmpq(int)
   Gmpq(int n)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:95:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘int’
/usr/local/include/CGAL/GMP/Gmpq_type.h:92:3: note: CGAL::Gmpq::Gmpq(const __mpq_struct*)
   Gmpq(const mpq_t q)
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:92:3: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const __mpq_struct*’
/usr/local/include/CGAL/GMP/Gmpq_type.h:90:3: note: CGAL::Gmpq::Gmpq()
   Gmpq() {}
   ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:90:3: note:   candidate expects 0 arguments, 1 provided
/usr/local/include/CGAL/GMP/Gmpq_type.h:69:7: note: CGAL::Gmpq::Gmpq(const CGAL::Gmpq&)
 class Gmpq
       ^
/usr/local/include/CGAL/GMP/Gmpq_type.h:69:7: note:   no known conversion for argument 1 from ‘const __gmp_expr<__mpq_struct [1], __mpq_struct [1]>’ to ‘const CGAL::Gmpq&’

1 ответ

Я думаю, что нашел решение: я должен был скомпилировать свою программу с флагом CGAL_USE_GMPXX

Другие вопросы по тегам