1 Fundamentals
A polynomial is either zero, or can be written as the sum of one or more non-zero terms. The number of terms is finite. A term consist of a constant coefficient and a monomial, that is, the product of zero or more variables. Each variable may have an exponent that is a non-negative integer. The exponent on a variable in a term is equal to the degree of that variable in that term. A term with no variables is called a constant term. The degree of a constant term is 0.
For example, −7x^3*y is a term. The coefficient is −7, the monomial is x^3y, comprised of the variables x and y, the degree of x is three, and the degree of y is one. The total degree of the entire term is the sum of the degrees in each variable. In the example above, the degree is 3+1=4.
多项式可以是0或有限多个非0项(term)。一个项包含一个常系数和一个单项式。单项式是一个0个或多个变量的乘积,每个变量有一个非负整数指数。这个指数的值等于这项内该变量的“度”(degree)。常数的度是0.
如,−7x^3*y是一个项,其系数是-7,单项式是x^3y,,由两个变量x和y组成,x的度是3,y的度是1.该项的总度数是3+1=4。
A one-variable (univariate) polynomial f of degree n has the following form:
The coefficient a0 is called the constant coefficient, an is called the leading coefficient. If f is not the zero polynomial the leading coefficient is not zero. The polynomial is called monic if an=1. In case the coefficient domain of f possess a greatest common divisor (gcd) the content of f is the gcd of all coefficients of f. For instance, the content of 12x3+6 is 6.
一个n度的单个变量(univariate)多项式是:f=anx^n+(an−1)x^(n−1)+...+a2x^2+a1x+a0
a0被称为常系数。如果f不是0多项式,则其leading coefficient则非0。如果an=1,则该多项式被称为“首一多项式”。如果f多项式中的系数集中的元素存在GCD,我们称该GCD为Content。
A multivariate polynomial is a polynomial in more than one variable. According to the number of variables it is possible to further classify multivariate polynomials as bivariate, trivariate etc. In contrast to univariate polynomials the terms of a multivariate polynomial are not completely ordered by their total degree. However, given a certain order on the variables it is possible to define a lexicographic order on the terms. Given this order the leading coefficient of a multivariate polynomial is defined as the coefficient of the highest term. For instance the leading coefficient of the multivariate polynomial p=5x3y+7xy2 is 7, given that y has an higher order than x.
一个多变量(multivariate)多项式可以分为2变量多项式、3变量多项式等。一个多变量多项式没有完全按其总度数排序。但给定一定的变量排序规则,则可能定义一个项的词典序。给定排序规则的多项式中,其leading系数被定义为度数最高的项系数。如:p=5x^3y+7xy^2中,如果定义y比x排序优先,则其leading系数为7。
However, it is also possible to interpret a multivariate polynomial as a univariate polynomial in that variable. For instance the trivariate polynomial
may be interpreted as a univariate polynomial in z, that is, q is interpreted as an element of R[z], with R=Z[x,y].
In this case the leading coefficient of q with respect to z is 13x1y2+7x2y1 and x5 becomes the 'constant' term.
多变量多项式也可以看作其中一个变量的是单变量多项式。
A homogeneous polynomial is a polynomial whose terms do all have the same total degree. For example, h=x5+7x2y1z2+13x1y2z2 is a homogeneous polynomial of degree 5, in three variables.
一个齐次多项式每个单项的总度数相等。
2 General Design
The package introduces a concept Polynomial_d
, a concept for multivariate polynomials in d variables. Though the concept is written for an arbitrary number of variables, the number of variables is considered as fixed for a particular model of Polynomial_d
. The concept also allows univariate polynomials.
First of all a model of Polynomial_d
is considered as an algebraic structure, that is, the ring operations {+,−,⋅} are provided due to the fact that Polynomial_d
refines at least the concept IntegralDomainWithoutDivision
. However, a model of Polynomial_d
has to be accompanied by a traits class Polynomial_traits_d<Polynomial_d>
being a model of PolynomialTraits_d
. This traits class provides all further functionalities on polynomials.
Given a d-variate polynomial over some base ring R there are at least two different possible views on such a polynomial.
- The recursive or univariate view: In this view, a polynomial is considered as an element of R[x0,…,xd−2][xd−1]. That is, the polynomial is treated as a univariate polynomial over the ring R[x0,…,xd−2].
- The symmetric or multivariate view: This view is almost symmetric with respect to all variables. It considers the polynomial as an element of R[x0,…,xd−1].
According to these two different views the traits class is required to provide two different coefficient types:
Polynomial_traits_d::Coefficient_type
representing R[x0,…,xd−2].Polynomial_traits_d::Innermost_coefficient_type
representing the base ring R.
Another important type which is introduced by this package is Exponent_vector
. It is derived from std::vector<int>
and used to identify multivariate monomials. For instance the exponent vector containing the sequence [3,2,4] corresponds to the trivariate monomial x30x21x42. Note that a vector with negative exponents is considered as invalid. However, we allow negative exponents as they may appear as intermediate results, in particular we did not derive from std::vector<unsigned int>
.
此包引入了一个Polynomial_d概念,它表示一个具有d个变量元多多项式。虽然本概念为任意数量的变量所创建,但对于每个特定的d其变量的数量是固定的。这个概念也允许单变量多项式。
首先,Polynomial_d被认为是一个代数结构,于是f需要提供环操作(Ring operation){+,-, *},因为本概念至少精炼于IntegralDomainWithoutDivision
.概念。一个Polynomial_d概念必须与一个traits类 Polynomial_traits_d<Polynomial_d>
相伴随,这个trait类是概念PolynomialTraits_d
.的模型。这个类提供了多项式的所有进一步操作。
给定在基本环(base ring)R上一个d变量的多项式,至少有两种视角来解释该多项式:
- 回归的或单变量视角。一个多项式被看作是一个单变量多项式,其他变量被看作系数。即其term可表示为R[x0,…,xd−2][xd−1],即一个环R[x0,…,xd−2]上的单变量多项式。
- 对称的或多变量视角。这个视角对所有的变量几乎是对称的。它将多项式看作环R[x0,…,xd−1]的一个元素。
按照此观点,traits类必须提供两种不同的系数类型:
Polynomial_traits_d::Coefficient_type
表示 R[x0,…,xd−2].Polynomial_traits_d::Innermost_coefficient_type
表示 base ring R.
另一个引入的重要的类型Exponent_vector。它是由std::vector<int>
扩展而来,用来识别多元单项式。如一个指数向量(exponent vector )包含序列[3,2,4]对应的3变量单项式为x03 *x12*x24。要注意的是向量中如果出现负的指数,将被认为是非法的。但是,我们仍然在中间结果中出现负的指数,特别是当这个向量不是从std::vector<unsigned int>
.扩展来的。
3 Constructing a Multivariate Polynomial
First of all the concept Polynomial_d
requires that the model is constructible from int. This is due to the fact that Polynomial_d
refines IntegralDomainWithoutDivision
which in turn refines FromIntConstructible
. Of course this allows only the construction of constant polynomials.
In general a polynomial is constructed using the functor Polynomial_traits_d::Construct_polynomial
a model of PolynomialTraits_d::ConstructPolynomial
. Basically there are two options:
- The polynomial is constructed from an iterator range with value type
Polynomial_traits_d::Coefficient_type
, where thebegin
iterator refers to the constant term (constant with respect to the outermost variable). - The polynomial is constructed from an iterator range with value type
std::pair<Exponent_vector, Polynomial_traits_d::Innermost_coefficient_type>
, where each pair defines the coefficient for the monomial defined by the exponent vector.
However, in some cases it might be more convenient to just construct the polynomials representing the different variables and to obtain the final polynomial using algebraic expressions. The most elegant way to construct a certain variable is Polynomial_traits_d::Shift
being a model of PolynomialTraits_d::Shift
.
Polynomial_d概念首先要求模型由int创建。这是由于Polynomial_d是精炼自IntegralDomainWithoutDivision,而IntegralDomainWithoutDivision又是精炼自FromIntConstructible
.。这当然允许构造常数多项式。
通常,一个多项式使用PolynomialTraits_d::ConstructPolynomial概念的模型——函子Polynomial_traits_d::Construct_polynomial构造。一般有两种选择:
- 使用类型由一个类型为Polynomial_traits_d::Coefficient_type的迭代器(terator range)构造,此时begin迭代器指向常数项(这一常数是相对于最外侧变量)。
- 使用类型由一个类型为
std::pair<Exponent_vector, Polynomial_traits_d::Innermost_coefficient_type>
的迭代器(terator range)构造,此时每个对(pair)定义由指数向量(exponent vector)定义的单项的系数。
在一些情况下,构造表示不同变量数的多项式最方便的方法是直接创建并通过代数表达式得到最后的多项式。创建一个变量最优雅的方法是通过Polynomial_traits_d::Shift,它是 PolynomialTraits_d::Shift的
一个模型。
3.1 Example
下面的例子是展示不同的2变量多项式的创建方法:
The following example illustrates different ways to construct a bivariate polynomial:
File Polynomial/construction.cpp
4 Coefficient Access
In order to obtain a certain coefficient the traits class provides several functors. Note that the functors do not allow a write access to the coefficients.
PolynomialTraits_d::GetCoefficient
: a model of this concept provides access to a coefficient in the univariate view, that is, it returns elements of R[x0,…,xd−2].PolynomialTraits_d::GetInnermostCoefficient
: a model of this concept provides access to a coefficient in the multivariate view, that is, it returns elements of R.PolynomialTraits_d::LeadingCoefficient
: a model of this concept provides access to the leading coefficient in the univariate view.PolynomialTraits_d::InnermostLeadingCoefficient
: a model of this concept provides access to the leading coefficient in the multivariate view, that is, it returns the (innermost) coefficient of the leading multivariate monomial. See alsoPolynomialTraits_d::DegreeVector
.
traits类提供了多种方法来取得系数。注意:functor是不可写入系数的。
4.1 Example
The following example illustrates the application of the functors discussed above:
File Polynomial/coefficient_access.cpp
5 Degree, Total Degree and Degree Vector
There are three functors in PolynomialTraits_d
related to the degree of a polynomial.
PolynomialTraits_d::Degree
: a model of this concept returns the degree of the polynomial in the univariate view. By default this is the degree with respect to the outermost variable, but it is also possible to select another variable.PolynomialTraits_d::TotalDegree
: a model of this concept returns the total degree of a polynomial. The polynomial is considered as a multivariate polynomial. The total degree is the maximum over the sums of the exponents of each multivariate monomial.PolynomialTraits_d::DegreeVector
: a model of this concept returns the exponent vector of the leading monomial, where the monomial order is lexicographic and starts with the outermost variable. See alsoPolynomialTraits_d::InnermostLeadingCoefficient
.
PolynomialTraits_d
的函子与多项式的度有关:5.1 Example
The following example illustrates the application of the functors discussed above:
File Polynomial/degree.cpp
6 Changing the Order of Variables
Given for instance a bivariate polynomial it is conceivable that one wants to interchange the role of x and y. That is one wants to interpret the x as y and vice versa. For such a case the polynomial traits provides PolynomialTraits_d::Swap
:
Given a polynomial p and to two indices i and j, the functor returns the polynomial in which xi is substituted by xj and vice versa, that is, the variables swap their positions. The order of the other variables remains untouched.
Another scenario is, that a particular variable should be moved to another position, for instance, it should become the outermost variable while the relative order of the other variables remains unchanged. For such a case the polynomial traits provides PolynomialTraits_d::Move
.
Of course there is also a general method to interchange the order of variables, namely PolynomialTraits_d::Permute
.
PolynomialTraits_d::Move
来实现此功能。6.1 Example
The following example illustrates the application of the functors discussed above:
File Polynomial/swap_move.cpp
7 GCD and More
Since the concept PolynomialTraits_d
refines the concept AlgebraicStructureTraits
the polynomial traits provides functors for integral division, division with remainder, greatest common divisor, etc. But note that the algebraic structure of a polynomial depends on the algebraic structure of the innermost coefficient, for instance, a gcd is available if and only if the innermost coefficient is a Field
or a UniqueFactorizationDomain
. Hence, we can not provide a gcd if the innermost coefficient is just an IntegralDomain
since it is simply not well defined[1]. However, if we would consider the polynomial over the quotient field of the integral domain the gcd would be well defined. The only problem is that the result can not be represented over the ring since it contains denominators. Therefore, the PolynomialTraits_d
requires functors such as PolynomialTraits_d::GcdUpToConstantFactor
. This functor computes the gcd of two polynomials up to a constant factor (utcf). That is, it returns the correct gcd for polynomials over the quotient field, but multiplied by some constant such that the result is representable with coefficients in the ring.
However, note that these 'utcf' functions are usually a bit faster than their strict counterparts. This is due to the fact that the 'utcf' functions are allowed to skip the computation of the correct constant factor. Note that in many cases the constant factor is in fact not needed. In particular if the polynomials are supposed to represent some zero set, that is, an algebraic curve or surface.
PolynomialTraits_d
概念精炼自 AlgebraicStructureTraits
概念,所以它提供了整数除法、带余数的除法和GCD等函子。请注意,多项式的代数结构依赖innermost coefficient(最内侧系数,即常数系数)的代数结构,如:当且仅当innermost coefficient 是一个Field(域)
或一个 UniqueFactorizationDomain时,才存在GCD。
所以,当innermost coefficient仅仅是 IntegralDomain
时,我们不能提供GCD,因为它没有被很好地定义。但是如果我们考虑在 IntegralDomain中的
quotient域的多项式时,则GCD则是很好的定义的。仅有的问题是:结果可能不会在环上,因为它包含了一个分母。所以,PolynomialTraits_d
要求如PolynomialTraits_d::GcdUpToConstantFactor的函子。这个函子计算两个多项式的GCD向上到一个常数因子(This functor computes the gcd of two polynomials up to a constant factor (utcf))即,这个函子返回多项式在Quotient field(域)的正确的GCD,但这个GCD被乘以某个常数使其结果能够被环中的系数所表达(but multiplied by some constant such that the result is representable with coefficients in the ring.)。
但是,这些utcf函数通常会比他们严格的counterpart快一点。这是由于utcf函数允许跳过计算正确的常数因子。在很多情况下,因子实际上不需要,特别是当多项式用于表达0集合(zero set)时,如一个代数曲线或表面。
与这些函子相关的概念包括:
The concepts for the related functors are:
-
AlgebraicStructureTraits::IntegralDivision
Another analog functionality is the pseudo division. The related functors replace the usual division with remainder in case the Polynomial is not a EuclideanRing
.
The concepts for the related functors are:
另一个模拟的功能是“伪除法”。当 Polynomial 不是一个EuclideanRing(欧几里德环)时,相关的函子用remainder (余数)代替了通常的除法。
与这些函子相关的概念有:
7.1 Example
The following example illustrates the application of some functors discussed above:
File Polynomial/gcd_up_to_constant_factor.cpp
8 Evaluation and Substitution
Of course, it should also be possible to evaluate a polynomial or substitute its variables. We also require a special functor to determine whether a polynomial is zero at a given point. In case the inner most coefficient is RealEmbeddable
the traits also must provide a function to compute the sign at a given point.
The concepts for the related functors are:
PolynomialTraits_d::Substitute //***!!!不知为何种操作
PolynomialTraits_d::Evaluate //***!!!求多项式在某处的值
PolynomialTraits_d::IsZeroAt
PolynomialTraits_d::SignAt
The traits is also required to provide variants of these functors that interpret the polynomial as a homogeneous polynomial by adding a virtual homogeneous variable such that each term has the same degree, namely the degree of the polynomial. Of course there is a difference between the univariate and multivariate view. For instance the polynomial
has degree 3, hence it is interpreted as the homogeneous polynomial
by adding the homogeneous variable w. In case of the multivariate view each term is filled up by the homogeneous variable such that the degree of each term is equal to the total degree of the polynomial.
Note that these functors may significantly improve efficiency. For instance, it is possible to determine the sign of a polynomial over integer coefficients at a rational point without changing the coefficient domain of the polynomial. For more details have a look at the following concepts:
评估一个多项式或替换其中的变量也是需要考虑的。我们也要求提供一个特别的函子要判断一个多项式在给定的点是否为0值。当最内侧的系数值是RealEmbeddable
时,traits必须能够提供一个函子来确定一个给定点的符号。
与这些函子相关的概念有:
PolynomialTraits_d::Substitute //***!!!用多项式去替换多项式中的变量
PolynomialTraits_d::Evaluate //***!!!求多项式在某处的值
PolynomialTraits_d::IsZeroAt
PolynomialTraits_d::SignAt
traits也要求提供这些函子的变种,通过增加一个虚拟的齐次变量,使每一项具有相同的度(这个度成为多项式的度),这样将多项式转换为齐次多项式。当然,单变量多项式和多变量视角存在一个不同点。 一个多项式:
5x^3+7x−3,具有3度。加入了一个齐次变量w将其转换为齐次多项式:5x^3+7xw^2−3w^3。
在多变量视角情况下,每项加入齐次变量使它的度等于多项式的总度。值得注意的是:这些函子可能会大大提高效率。如:在一个有理数点计算一个整数系数多项式的符号时,可以不改变系数的定义域(domain)(it is possible to determine the sign of a polynomial over integer coefficients at a rational point without changing the coefficient domain of the polynomial. For more details have a look at the following concepts:)。下面的概念提供了更多细节:
PolynomialTraits_d::SubstituteHomogeneous //***!!!将多项式看作是一个齐次多项式,然后进行替换(包括对齐次变量的替换)
PolynomialTraits_d::EvaluateHomogeneous
//***!!!将多项式看作是一个齐次多项式,然后进行求值(包括对齐次变量的求值)PolynomialTraits_d::IsZeroAtHomogeneous
PolynomialTraits_d::SignAtHomogeneous
Note that substitute allows the substitution of the variables by any type that is ExplicitInteroperable
with the innermost coefficient type. This is a very powerful tool since it allows the substitution of the variables by polynomials. However, for some standard manipulations such as translation or scaling we require special functors since they are expected to be faster than their equivalent implementation using substitution:
PolynomialTraits_d::Shift
PolynomialTraits_d::Negate
PolynomialTraits_d::Invert
PolynomialTraits_d::Translate //***!!!这个函子是什么作用?
PolynomialTraits_d::TranslateHomogeneous //***!!!这个函子是什么作用?
PolynomialTraits_d::Scale
PolynomialTraits_d::ScaleHomogeneous //***!!!这个函子是什么作用?
注意:这样的替换操作允许使用与最内侧系数( innermost coefficient ,即常系数)类型可实现显示互操作的所有类型进行变量的替换。这是非常强大的工具,因为它允许用多项式来替换变量。
但是,我们需要一些特殊的函子来执行一些标准的操作,如转换或缩放。这样我们希望这些函子要快于基于替换的同样操作的实现。它们有:
PolynomialTraits_d::Shift //***!!!单个变量的项生成
PolynomialTraits_d::Negate
//***!!!取反PolynomialTraits_d::Invert
//***!!!不知其含义PolynomialTraits_d::Translate
//***!!!不知其含义PolynomialTraits_d::TranslateHomogeneous
//***!!!不知其含义PolynomialTraits_d::Scale
//***!!!不知其含义PolynomialTraits_d::ScaleHomogeneous
//***!!!不知其含义
8.1 Example
The following example illustrates the application of some functors discussed above:
File Polynomial/substitute.cpp
9 Resultants, Subresultants and Sturm-Habicht Sequences(结式,子结式及Sturm-Habicht序列)
结式(eliminant或resultant)是代数学术语,指由两个多项式的系数所构成的一种行列式,或称Sylvester行列式,结式可判断两个多项式是否有公根、是否互素,以及判断多项式是否有重根。
The PolynomialTraits_d
concept also provides more sophisticated functors for computations with polynomials - computing the resultant of two polynomials, their polynomial subresultant sequence, with or without cofactors, and their principal subresultant coefficients.
PolynomialTraits_d::Resultant
PolynomialTraits_d::PolynomialSubresultants
/***!!!这个函子是什么作用?PolynomialTraits_d::PolynomialSubresultantsWithCofactors
/***!!!这个函子是什么作用?PolynomialTraits_d::PrincipalSubresultants
/***!!!这个函子是什么作用?
Moreover, functors to compute the Sturm-Habicht sequence, with or without cofactors, and for the principal Sturm-Habicht coefficients exist.
PolynomialTraits_d::SturmHabichtSequence
PolynomialTraits_d::SturmHabichtSequenceWithCofactors
PolynomialTraits_d::PrincipalSturmHabichtSequence
For a formal definition of all used terms, we refer to the corresponding reference pages.
另外,计算Sturm-Habicht序列的函子(或仿函数),带或不带余子式时,以及主Sturm-Habicht因子存在时的方法如下:
PolynomialTraits_d::SturmHabichtSequence
PolynomialTraits_d::SturmHabichtSequenceWithCofactors
PolynomialTraits_d::PrincipalSturmHabichtSequence
上面所有术语的形式化定义在相应的参考页给出。
The principal Sturm-Habicht sequence allows to count the number of real roots of a polynomial using the function
As input, this function requires an iterator range that represents the principal Sturm-Habicht coefficients. This might look complicated at a first sight, as one has to store the principal Sturm-Habicht sequence temporarily. However, we remark an important property of the (principal) Sturm-Habicht sequence. Having a polynomial ft(x) that depends on a parameter t, and its (principal) Sturm-Habicht coefficients stha0(ft),…,sthan(ft), evaluating stha0(ft) for t=t0 yields a valid (principal) Sturm-Habicht sequence for ft0. The same holds for (principal) subresultants. Thus, it is enough in such situations to compute the sequence once for the parameter t, and call number_of_real_roots()
for each specialized parameter value.
We finally remark that computing subresultants and Sturm-Habicht sequences introduces an enormous coefficient blow-up. An application of the functors therefore does not make sense for built-in integers except for toy examples. To avoid overflows, one should use arbitrary size integer types in real applications.
主Sturm-Habicht序列可以用下面的函数来计算一个多项式的实数根的个数:
这个函数要求一个表示Sturm-Habicht系数序列的迭代器作为输入。最初看上去有点复杂,因为要将主Sturm-Habicht 序列进行暂存。但我们注意到Sturm-Habicht序列的一个重要的性质。考虑一个依赖参数t的多项式ft(x),它的(主)Sturm-Habicht系数为 stha0(ft),…,sthan(ft), 当t=t0时对stha0(ft) 求值生成一个ft0 的合法的Sturm-Habicht 序列。这对于 (principal) subresultants同样成立。这种条件对于计算参数t的序列和对每个特定参数值调用number_of_real_roots() 是足够的(Thus, it is enough in such situations to compute the sequence once for the parameter t, and call number_of_real_roots()
for each specialized parameter value)。
最后需要注意的是:对subresultants和 Sturm-Habicht sequences的计算可能引入很多的系数放大(blow-up)。于是使用这些函数的应用除了toy examples就没法搞清内置整数( An application of the functors therefore does not make sense for built-in integers except for toy examples.),为解决这一问题,我们在实际应用中应当使用任意精度整数(arbitrary size integer)类型。
9.1 Example
The following example illustrates how two compute resultants of two polynomials, and how to count the number of distinct real roots of a polynomial using its principal Sturm-Habicht coefficients.
File Polynomial/subresultants.cpp
resultant