1. 代数基础 Algebraic Foundations
Michael Hemmer
This package defines what algebra means for CGAL, in terms of concepts, classes and functions. The main features are: (i) explicit concepts for interoperability of types (ii) separation between algebraic types (not necessarily embeddable into the reals), and number types (embeddable into the reals).
User Manual Reference Manual
{+,-,*}
is_zero(x)
gcd(x,y)
迈克尔·海默
这个包从概念、类和函数的角度定义了代数对CGAL的意义。主要特征是:(i)类型互操作性的明确概念(ii)代数类型(不一定嵌入real)和数字类型(嵌入real)之间的分离。
2.用户手册
2.1 简介
CGAL的目标是精确计算非线性对象,特别是定义在代数曲线和曲面上的对象。作为表示多项式的结果类型,代数扩张和有限域在相关实现中扮演着更重要的角色。为了跟上这些变化,引入了这个包。由于引入的框架必须支持特定的多项式,因此包避免了术语数类型。相反,包区分了类型的代数结构和类型是可嵌入在实轴上,还是可嵌入在实轴上。此外,该包引入了可互操作类型的概念,允许显式处理混合操作。
2.2 代数结构
本节中介绍的代数结构概念是由传统代数中著名的对应概念驱动的,但我们也必须赞扬现有的类型及其限制。为了保持界面最小,不希望覆盖所有已知的代数结构,例如,我们没有为诸如群之类的基本结构或诸如斜场之类的特殊结构引入概念。
2.1 Tags in Algebraic Structure Traits
2.3 Exact and Numerical Sensitive
如果类型的性能对算法的条件数敏感,则代数结构被认为是数值敏感的。请注意,这两个概念之间确实存在差异,例如,基本类型int
对数值不敏感,但由于溢出而被认为是不精确的。相反,leda_real
或CORE::Expr
类型是精确的,但由于内部使用了多精度浮点运算,因此对数值问题非常敏感。我们期望Is_numerical_sensitive
用于分派算法,而Is_exact
用于启用只能检查精确类型的断言。
Tags are very useful to dispatch between alternative implementations. The following example illustrates a dispatch for Fields using overloaded functions. The example only needs two overloads since the algebraic category tags reflect the algebraic structure hierarchy.
标记对于在不同的实现之间进行调度非常有用。下面的示例演示了使用重载函数对字段的分派。该示例只需要两个重载,因为代数类别标记反映了代数结构层次结构。
File Algebraic_foundations/algebraic_structure_dispatch.cpp
4实数类型
每个CGAL
内核都有两种实数类型(可嵌入实数中的数字类型)。其中一个是FieldNumberType
,另一个是RingNumberType
。基本内核对象(点、向量等)的坐标来自其中一种类型(对于笛卡尔核为FieldNumberType
,对于齐次核为RingNumberType
)。
FieldNumberType
概念结合了concepts
字段和RealEmbeddeble
的要求,而RingNumberType
结合了Integrationdomainwithoutdivision
和RealEmbeddeble
。代数上,实数类型不形成不同的结构,因此不在图1.1的概念层次中列出。
5互操作性 Interoperability
本节介绍了类型互操作性的两个概念,即隐式可操作和显式可操作。虽然ExplicitInteroperable
是基本概念,但我们从隐式可操作开始,因为它是更直观的概念。
通常,混合操作是由重载的运算符和函数提供的,或者只是通过隐式构造函数调用提供的。这种程度的互操作性反映在隐式可操作的概念上。但是,在模板代码中,混合算术操作的结果类型或所谓的强制类型可能不清楚。因此,包引入了强制特性,通过强制特性<A,B>::
类型访问两个可互操作类型A和B的强制类型。
一些简单的例子是int
和double
(带强制类型double)或Gmpz
和Gmpq
(带强制类型Gmpq
)。然而,强制类型不一定是输入类型之一,例如,具有整数系数的多项式乘以有理类型的强制类型被假定为具有有理系数的多项式。
强制特性还需要提供从输入类型转换为强制类型的函子强制特性<a,B>::Cast()
。这实际上是可解释的更基本概念的核心。ExplicitInteroperable
已经被引入到更复杂的情况中,对于这些情况,很难或不可能保证隐式的互操作性。注意,这个函子对于隐式可操作类型也很有用,因为它可以用来避免冗余的类型转换。
如果两个类型A和B可以用强制类型C来解释,则它们是由C的代数结构特征和实嵌入特征所提供的所有二元函子的有效参数类型,对于相应的全局函数也是如此。
5.1 Examples
The following example illustrates how two write code for ExplicitInteroperable
types.
File Algebraic_foundations/interoperable.cpp
File Algebraic_foundations/implicit_interoperable_dispatch.cpp
6 Fractions
除了需要对整个对象执行代数运算外,还需要将数字类型分解为分子和分母。这不仅适用于作为商的Quotient
、gmpq、mpq_class
或 leda_rational
,也适用于作为Sqrt_扩展或多项式的复合对象,该复合对象可以分解为(标量)分母和具有更简单系数类型(例如整数而不是有理数)的复合分子。在这些无分母乘法上,通常可以更快地执行运算。如果类型是分数,则相关功能以及分子和分母类型由分数特性提供。特别是分数特性提供了一个可以用于分派的标记是分数。
一个相关的类是由于向后兼容的原因而保留的有理特性。但是,我们建议使用分数特性,因为它更通用,并提供分派功能。
6.1 Examples
The following example show a simple use of Fraction_traits:
File Algebraic_foundations/fraction_traits.cpp
下例说明向量的积分,即多项式的系数向量。注意,为了使系数增长分数最小,使用Fraction_traits::Common_factor计算分母的最小公倍数。