【问题标题】:CGAL filtered kernel without lazy evaluation没有惰性求值的 CGAL 过滤内核
【发布时间】:2017-08-04 13:54:22
【问题描述】:

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

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

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

  • exact_predicates_inexact_constructions_kernel 是线程安全的,但它将坐标存储为双精度值。
  • 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&’

【问题讨论】:

  • 在此处复制编译器错误消息会有所帮助。
  • 谢谢。我用一个最小的例子和错误消息编辑了这个问题。
  • 我可以重现它。我通过确保 CMake 在安装时发现 GMPXX 来修复它。这会导致在 中启用#define CGAL_USE GMPXX,从而使 Filtered_kernel 在这里工作。

标签: geometry thread-safety cgal


【解决方案1】:

我想我找到了解决方案:我应该用标志 CGAL_USE_GMPXX 编译我的程序

【讨论】:

    猜你喜欢
    • 2017-02-11
    • 1970-01-01
    • 2010-10-30
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多