CGAL过滤内核而没有延迟评估

时间:2017-08-04 13:54:22

标签: geometry thread-safety cgal

我一直在研究CGAL,我在尝试定义满足我需要的内核时遇到了麻烦。

我需要一个线程安全的内核,但同时我想存储精确的坐标。

如果我理解正确的CGAL文档:

  • exact_predicates_inexact_constructions_kernel是线程安全的,但它将坐标存储为double值。
  • exact_predicates_exact_constructions_kernel存储确切的坐标,但不是线程安全的(因为数字类型很懒)。
  • CGAL :: Simple_cartesian是线程安全的,并准确存储坐标。但是,我的应用程序要慢得多。

我基本上得出结论,我需要类似的东西:

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

(使用过滤间隔算法来提高性能的内核,存储精确坐标(将在过滤器失败时使用)并且不使用惰性数字类型)。

我认为这个内核比exact_predicates_exact_constructions_kernel慢,但是它比线程安全且比非过滤内核快得多。 (此外,我认为惰性数字类型对我的应用程序不会那么有用,因为我想要输出精确的坐标,因此,它们必须在某个时刻计算 - 也就是说,我需要的唯一“优化”是快速过滤的谓词)

问题是:我尝试用这个内核编译测试应用程序,编译总是失败。有没有理由我不能创建一个不仅保留浮点间隔而且保留精确坐标的过滤内核?

PS:我在Linux上使用CGAL 4.10

谢谢!

更新: 失败的最小示例:

#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 个答案:

答案 0 :(得分:0)

我想我找到了一个解决方案:我应该用标志CGAL_USE_GMPXX

编译我的程序