Studying and solving polynomial systems with the RegularChains library
Parisa Alvandi, Changbo Chen, James Davenport, Juergen Gerhard, Mahsa Kazemi, Francois Lemaire, Liyun Li, Xin Li, John May, Marc Moreno Maza, Wei Pan, Bican Xia, Rong Xiao, and Yuzhen Xie
1. Introduction
The RegularChains library offers a variety of commands for solving polynomial systems symbolically and studying their solutions. The input systems may contain polynomial equations p=0, polynomial inequations p≠0, and polynomial inequalities p>0 or p≥0. All of those may be nonlinear. For a given system, the coefficients of the input polynomials may be rational numbers, integers modulo a prime, or polynomials depending on parameters. The solution sets computed by the RegularChains library are described by lists of components. Geometrically, such a component can be a point (or a set of points), a curve (or a set of curves), a surface (or a set of surfaces), etc. Computationally, components are represented by a special kind of polynomial system with a triangular shape and other algebraic properties. Depending if the input system consists of equations only, has inequations but no inequalities, or possesses inequalities, the system representing a component is called a regular chain, a regular system or a regular semi-algebraic system, respectively. The word "regular" refers to the interesting algebraic properties that these systems have. The RegularChains library provides types for these different kinds of polynomial systems; this important feature will be illustrated hereafter.
Another design feature of the RegularChains library is the organization of its 146 commands into 8 modules. The top-level of the library gathers the most commonly used commands, whereas the six submodules are dedicated to special topics. The submodules ChainTools, ConstructibleSetTools, and SemiAlgebraicSetTools deal respectively with specific operations on regular chains, regular systems, and regular semi-algebraic systems. The submodule MatrixTools allows the user to handle linear systems over domains with zero-divisors. This is a fundamental tool in the theory of regular chains with many potential applications. The AlgebraicGeometryTools submodule provides facilities for studying algebraic curves, surfaces and algebraic sets of higher dimension.
The submodule ParametricSystemTools is devoted to solving systems with parameters, including real root classification and complex root classification of such systems, as demonstrated below. Finally, the submodule FastArithmeticTools provides highly optimized implementation of some fundamental operations on regular chains, similar to some commands of the top-level module and ChainTools. However, the commands of this submodule can only be used under some assumptions and their usage requires care and advanced knowledge.
restart; with(RegularChains); with(ChainTools); with(MatrixTools); with(ConstructibleSetTools); with(ParametricSystemTools); with(SemiAlgebraicSetTools); with(FastArithmeticTools); with(AlgebraicGeometryTools);
AlgebraicGeometryTools,ChainTools,ConstructibleSetTools,Display,DisplayPolynomialRing,Equations,ExtendedRegularGcd,FastArithmeticTools,Inequations,Info,Initial,Intersect,Inverse,IsRegular,LazyRealTriangularize,MainDegree,MainVariable,MatrixCombine,MatrixTools,NormalForm,ParametricSystemTools,PolynomialRing,Rank,RealTriangularize,RegularGcd,RegularizeInitial,SamplePoints,SemiAlgebraicSetTools,Separant,SparsePseudoRemainder,SuggestVariableOrder,Tail,Triangularize
Chain,ChangeOfCoordinates,ChangeOfOrder,Construct,Cut,DahanSchostTransform,Dimension,Empty,EqualSaturatedIdeals,EquiprojectableDecomposition,Extend,ExtendedNormalizedGcd,IsAlgebraic,IsEmptyChain,IsInRadical,IsInSaturate,IsIncluded,IsPrimitive,IsStronglyNormalized,IsZeroDimensional,IteratedResultant,LastSubresultant,Lift,ListConstruct,NormalizeRegularChain,NumberOfSolutions,Polynomial,Regularize,RemoveRedundantComponents,SeparateSolutions,Squarefree,SquarefreeFactorization,SubresultantChain,SubresultantOfIndex,Under,Upper
IsZeroMatrix,JacobianMatrix,LowerEchelonForm,MatrixInverse,MatrixMultiply,MatrixOverChain
Complement,ConstructibleSet,CylindricalDecompose,Difference,EmptyConstructibleSet,GeneralConstruct,Intersection,IsContained,IsEmpty,MakePairwiseDisjoint,PolynomialMapImage,PolynomialMapPreimage,Projection,QuasiComponent,RationalMapImage,RationalMapPreimage,RefiningPartition,RegularSystem,RegularSystemDifference,RepresentingChain,RepresentingInequations,RepresentingRegularSystems,SeparateZeros,Union
BelongsTo,BorderPolynomial,CoefficientsInParameters,ComplexRootClassification,ComprehensiveTriangularize,DefiningSet,DiscriminantSequence,DiscriminantSet,PreComprehensiveTriangularize,RealComprehensiveTriangularize,RealRootClassification,Specialize
BoxValues,Complement,CylindricalAlgebraicDecompose,Difference,DisplayParametricBox,DisplayQuantifierFreeFormula,EmptySemiAlgebraicSet,Intersection,IsContained,IsEmpty,IsParametricBox,LinearSolve,PartialCylindricalAlgebraicDecomposition,PositiveInequalities,Projection,QuantifierElimination,RealRootCounting,RealRootIsolate,RefineBox,RefineListBox,RemoveRedundantComponents,RepresentingBox,RepresentingChain,RepresentingQuantifierFreeFormula,RepresentingRootIndex,SignAtBox,VariableOrdering
BivariateModularTriangularize,IteratedResultantDim0,IteratedResultantDim1,NormalFormDim0,NormalizePolynomialDim0,NormalizeRegularChainDim0,RandomRegularChainDim0,RandomRegularChainDim1,ReduceCoefficientsDim0,RegularGcdBySpecializationCube,RegularizeDim0,ResultantBySpecializationCube,SubresultantChainSpecializationCube
Cylindrify,IntersectionMultiplicity,IsTransverse,LimitPoints,RationalFunctionLimit,RegularChainBranches,TangentCone,TangentPlane,TriangularizeWithMultiplicity
2. Polynomial systems and regular chains
This section introduces the user to the top-level module of the RegularChains library. The concept of a regular chain is based on a recursive and univariate vision of a polynomial. Several commands manipulating polynomials in this manner are illustrated below. The most commonly used command of the library is called Triangularize and is illustrated by several examples. It takes a polynomial system as input and returns a description of its solution set. If the input system consists of equations only, then this description is a list of regular chains. The case where the input system admits inequations can be handled by Triangularize or by the command GeneralConstruct of the ConstructibleSetTools submodule. In case of inequalities, and more generally for computing the real solutions of a polynomial system, the commands RealTriangularize, LazyRealTriangularize and SamplePoints of the top-level module can be used. Different commands are also available in the modules ParametricSystemTools and SemiAlgebraicSetTools for the same purpose of real solving but for particular types of systems: they will be presented later in this document.
2.1 A univariate vision of polynomials
Define the polynomial ring ℚx,y,z with the variable ordering x>y>z. The field ℚ of rational numbers is the default coefficient ring.
R := PolynomialRing([x, y, z]);
R≔polynomial_ring
The internal representation of this polynomial ring can be accessed as follows.
Display(R);
Variables:⁢x,y,zParameters:⁢∅Characteristic:⁢0
Consider the following polynomial.
p := (y+1)*x^3+(z+4)*x+3;
p≔y+1⁢x3+z+4⁢x+3
The main variable of p as a polynomial of R is given by:
y+1⁢x3+z+4⁢x+3
polynomial_ring
MainVariable(p, R);
x
The initial (or leading coefficient) of p:
Initial(p, R);
y+1
The degree of p in the main variable:
MainDegree(p, R);
3
The rank of p, which is the main variable of p raised to the main degree of p:
Rank(p, R);
x3
The tail of p.
Tail(p, R);
x⁢z+4⁢x+3
The separant of p, which is the derivative of p with regards to its main variable:
Separant(p, R);
3⁢x2⁢y+3⁢x2+z+4
Change the ordering to z>y>x:
R := PolynomialRing([z, y, x]); Display(R); p := expand((y+1)*x^3+(z+4)*x+3); MainVariable(p, R); Initial(p, R); Rank(p, R); Tail(p, R); Separant(p, R);
Variables:⁢z,y,xParameters:⁢∅Characteristic:⁢0
p≔x3⁢y+x3+x⁢z+4⁢x+3
z
x3⁢y+x3+4⁢x+3
Consider the polynomial ring ℤ3z,y,x with the ordering z>y>x.
R := PolynomialRing([z, y, x], 3); Display(R); Initial(p, R); Tail(p, R);
Variables:⁢z,y,xParameters:⁢∅Characteristic:⁢3
x3⁢y+x3+x
2.2 Computing the subresultants of two polynomials
The command SubresultantChain in the ChainTools module is used to compute the subresultant chain of two polynomials. Let us illustrate this by an example.
Define a ring of polynomials.
R := PolynomialRing([y, x]);
Define two polynomials of R.
f1 := (y^2+6)*(x-1)-y*(x^2+1);
f1≔y2+6⁢x−1−y⁢x2+1
f2 := (x^2+6)*(y-1)-x*(y^2+1);
f2≔x2+6⁢y−1−x⁢y2+1
Compute their subresultant chain w.r.t the variable y
src := SubresultantChain(f1, f2, y, R);
src≔subresultant_chain
The result is of type subresultant_chain and encodes all the polynomials in the subresultant chain. To display the ith subresulant polynomial, one can call the command SubresultantOfIndex. For example, to know the subresultant of index 0, that is the resultant, one can do as follows
res := SubresultantOfIndex(0, src, R);
res≔2⁢x6−22⁢x5+102⁢x4−274⁢x3+488⁢x2−552⁢x+288
To display all the subresultant polynomials, one can call the command Display.
Display(src, R);
−x2+5⁢x−6⁢y−x3+6⁢x2−11⁢x+62⁢x6−22⁢x5+102⁢x4−274⁢x3+488⁢x2−552⁢x+288
The encoding of the subresultants can be controlled by an optional argument. This encoding can be by values, over the monomial basis or via the Bezout Matrix.
When this optional argument is not specified, the encoding is chosen according to a heuristical algorithm.
src := SubresultantChain(f1, f2, y, R, representation = BezoutMatrix); op(src);
table⁡SRC_MDEG=1,SRC_POLYQ=x2⁢y−x⁢y2−x2−x+6⁢y−6,representation=BezoutMatrix,SRC_MVAR=y,type=subresultant_chain,SRC_MATRIX=−x2+5⁢x−6−x3+6⁢x2−11⁢x+6−x3+6⁢x2−11⁢x+6x4−5⁢x3+13⁢x2−35⁢x+42,SRC_POLYP=−x2⁢y+x⁢y2−y2+6⁢x−y−6
src := SubresultantChain(f1, f2, y, R, representation = MonomialBasis); op(src);
table⁡SRC_MDEG=1,SRC_POLYQ=x2⁢y−x⁢y2−x2−x+6⁢y−6,representation=MonomialBasis,SRC_MVAR=y,subresultant_chain_vector=2⁢x6−22⁢x5+102⁢x4−274⁢x3+488⁢x2−552⁢x+288,−x3−x2⁢y+6⁢x2+5⁢x⁢y−11⁢x−6⁢y+6,x2⁢y−x⁢y2−x2−x+6⁢y−6,−x2⁢y+x⁢y2−y2+6⁢x−y−6,type=subresultant_chain,SRC_POLYP=−x2⁢y+x⁢y2−y2+6⁢x−y−6
2.3 Solving systems of equations with regular chains
Define a set of polynomials of R.
sys := {x+y+z^2-1, x+y^2+z-1, x^2+y+z-1};
sys≔z2+x+y−1,y2+x+z−1,x2+y+z−1
Ideally, one would like to decompose the solutions of sys into a list of points. This is what the command Triangularize does using symbolic expressions. In the output decomposition, some points are grouped because they share some properties. These groups are called regular chains.
A regular chain is a system of equations and inequations, satisfying special algebraic properties. First, the equation part consists of non-constant polynomials with pairwise different main variables; thus, the equation part has a triangular shape. Second, the inequation part consists of the initials of the polynomials defining the equations; moreover, the product of those initials is regular (that is, not a zero-divisor) modulo the saturated ideal of the equation part. This technical condition can be skipped by the non-expert reader, since in most practical examples the inequations are trivial and can be ignored. This is the case in our example where all initials are equal to 1, leading to trivial inequations.
l := Triangularize(sys, R);
l≔regular_chain,regular_chain,regular_chain,regular_chain
map(Equations, l, R); map(Inequations, l, R); map(NumberOfSolutions, l, R);
x−z,y−z,z2+2⁢z−1,x,y,z−1,x,y−1,z,x−1,y,z
∅,∅,∅,∅
2,1,1,1
The result is to be interpreted as follows: The system sys is equivalent to a union of four regular chains. The equations for the first such regular chain are x−1=y=z=0, the equations for the second regular chain are x=y−1=z=0, etc. None of the four regular chains have any inequations. The first three regular chains have exactly one solution, and the last one has two solutions.
Note that you can also specify inequations of the form p≠0. For example, you can specify that x−z must not vanish.
l := Triangularize(sys, [x-z], R); map(Equations, l, R); map(NumberOfSolutions, l, R);
l≔regular_chain,regular_chain
x−1,y,z,x,y,z−1
1,1
2.4 Solving polynomial systems with infinitely many solutions
In the previous examples, the polynomial systems have finitely many solutions. To illustrate how the Triangularize command handles systems with infinitely many solutions, consider the following parametric linear system with unknowns x,y and parameters a,b,c,d,g,h.
R := PolynomialRing([x, y, a, b, c, d, g, h]); sys := {a*x+b*y-g, c*x+d*y-h};
sys≔a⁢x+b⁢y−g,c⁢x+d⁢y−h
By default, the Triangularize command computes the generic solutions of the input system. For this parametric linear system, this implies its determinant is assumed to be nonzero.
l := Triangularize(sys, R); map(Equations, l, R); map(Inequations, l, R);
l≔regular_chain
c⁢x+y⁢d−h,a⁢d−b⁢c⁢y−a⁢h+c⁢g
c,d⁢a−b⁢c
Thus, the resulting regular chain consists of the two equations c x+d y−h=a d−b cy+c g−a h=0 and the two inequations c≠0≠a d−b c, the first of which reflects the choice of c as a pivot.
The other available Maple commands for solving such a system do a similar job.
solve(sys, {x, y});
x=−b⁢h−d⁢gd⁢a−b⁢c,y=a⁢h−c⁢gd⁢a−b⁢c
Groebner[Solve](sys, {x, y});
d⁢x⁢a−b⁢c⁢x+b⁢h−d⁢g,y⁢a⁢d−y⁢b⁢c−a⁢h+c⁢g,plex⁡y,x,∅
The Triangularize command can do more if the option "output=lazard" is used. In this case, all the solutions of the input are computed, generic or not. This implies that the case where the determinant vanishes is also considered and solved. For each regular chain below, its equations and inequations are printed.
l := Triangularize(sys, R, output = lazard): seq(Display(l[i], R), i = 1..nops(l));
c⁢x+d⁢y−h=0d⁢a−b⁢c⁢y−h⁢a+c⁢g=0d⁢a−b⁢c≠0c≠0,c⁢x+d⁢y−h=0d⁢a−b⁢c=0h⁢b−d⁢g=0c≠0d≠0h≠0,a⁢x+b⁢y−g=0d⁢y−h=0c=0a≠0d≠0,d⁢y−h=0a=0h⁢b−d⁢g=0c=0d≠0h≠0,c⁢x−h=0h⁢a−c⁢g=0b=0d=0c≠0h≠0,a⁢x+b⁢y−g=0c=0d=0h=0a≠0,c⁢x+d⁢y=0d⁢a−b⁢c=0g=0h=0c≠0d≠0,b⁢y−g=0a=0c=0d=0h=0b≠0,y=0a=0c=0g=0h=0,x=0b=0d=0g=0h=0,a=0b=0c=0d=0g=0h=0
One may also want to "push" some parameters into the field of coefficients, that is, to solve over a field of rational functions. Consider a new polynomial ring over the field ℚg,h of rational functions in g and h.
R2≔PolynomialRingx,y,a,b,c,d,g,h:l≔Triangularizesys,R2,output=lazard: seqDisplayli, R2, i=1..nopsl;
c⁢x+d⁢y−h=0d⁢a−b⁢c⁢y−h⁢a+c⁢g=0d⁢a−b⁢c≠0c≠0,c⁢x+d⁢y−h=0d⁢a−b⁢c=0h⁢b−d⁢g=0c≠0d≠0,a⁢x+y⁢b−g=0d⁢y−h=0c=0a≠0d≠0,d⁢y−h=0a=0h⁢b−d⁢g=0c=0d≠0,c⁢x−h=0h⁢a−c⁢g=0b=0d=0c≠0
Finally, we solve over ℤ3g,h, that is, over the field of rational functions in g and h modulo 3.
R3:=PolynomialRing⁡x,y,a,b,c,d,g,h,3;l:=Triangularize⁡sys,R3,output=lazard;opDisplayl, R3;
R3≔polynomial_ring
l≔regular_chain,regular_chain,regular_chain,regular_chain,regular_chain
c⁢x+d⁢y+2⁢h=0d⁢a+2⁢b⁢c⁢y+2⁢h⁢a+c⁢g=0d⁢a+2⁢b⁢c≠0c≠0,c⁢x+d⁢y+2⁢h=0d⁢a+2⁢b⁢c=0h⁢b+2⁢d⁢g=0c≠0d≠0,a⁢x+y⁢b+2⁢g=0d⁢y+2⁢h=0c=0a≠0d≠0,d⁢y+2⁢h=0a=0h⁢b+2⁢d⁢g=0c=0d≠0,c⁢x+2⁢h=0h⁢a+2⁢c⁢g=0b=0d=0c≠0
2.5 Regular chains and polynomial gcds
The main subroutine of the Triangularize command is the RegularGcd command, which computes polynomial gcds modulo regular chains. This routine is illustrated hereafter together with basic commands on regular chains from the ChainTools submodule.
Here's the empty regular chain and its internal representation.
Empty(R); op(Empty(R));
regular_chain
property,polynomials,type,ModulePrint,moduleoptionrecord;exportproperty,polynomials,type,ModulePrint;end module
You can construct a new regular chain by adding a (suitable) polynomial p to an existing regular chain T. This operation may return a list of regular chains. Indeed, checking that the initial of p is regular with regards to (the saturated ideal of) T may split T.
On the example below, this does not happen; the regular chain T is empty.
l := Construct(x^2+1, Empty(R), R); rc := l[1];
rc≔regular_chain
The internal representation of the new regular chain rc is as follows. For each polynomial in the regular chain, the data structure stores its main variable, its main degree, and its initial. These quantities are needed quite frequently and are therefore cached to avoid recomputing them each time they are needed.
The internal representation also shows a property about the regular chain: isPrime. This means that its saturated ideal is a prime ideal. The knowledge of such property helps to speed up computations.
op(rc);
Now compute the greatest common divisor of two polynomials p1and p2modulo rc. The example is designed such that y+1 is a gcd.
p1:=expand⁡x+1⋅y+x⋅y+1;p2≔expandx−1⋅y+x⋅y+1;
p1≔x⁢y2+2⁢x⁢y+y2+x+y
p2≔x⁢y2+2⁢x⁢y−y2+x−y
In general, the output of a gcd computation modulo a regular chain is a list of "cases".
In the above example, no case splits can happen since rc defines a field. However, note that the output, below, is not exactly the one expected.
rg:=RegularGcd⁡p1,p2,y,rc,R;factor⁡rg11
rg≔2⁢x⁢y+2⁢x,regular_chain
2⁢x⁢y+1
However, the extraneous factor 2 x is a unit modulo rc. Thus, the expected and the computed gcds are in fact associate, and therefore the result is correct.
Consider an example where a split is necessary during a gcd computation. To create such an example, you need to make sure that the input equations do not factor, because otherwise the Construct command will already split the system. The example below has three variables; the two variables x and y are used for building a regular chain with two polynomials mx and my.
R := PolynomialRing([z, y, x]);
The first polynomial is irreducible over <.
mx := x^2-2;
mx≔x2−2
Thus, constructing a regular chain from it produces a single output. Make a copy of it for later use.
rc := Construct(mx, Empty(R), R)[1]; rcx := rc;
rcx≔rc
The Construct command has detected that (the saturated ideal of) rc is a prime ideal.
The second polynomial is not irreducible in ℚxy. The Construct command would easily discover this fact and would split it when constructing a regular chain involving rc.
my := expand((y-x)*(y+x-1));
my≔−x2+y2+x−y
By reducing my modulo rc, the reduced polynomial becomes irreducible in ℚxy.
my := SparsePseudoRemainder(my, rc, R);
my≔y2+x−y−2
Extend rc by my.
l := Construct(my, rc, R);rc := l[1];
The Construct command uses inexpensive criteria to detect whether the associated saturated ideal is prime or not. These criteria fail here. So the constructed regular chain rc has no particular properties.
op(rc);Equations(rc, R);
y2−y+x−2,x2−2
Compute the gcd of p1 and p2, defined below, modulo rc.
p1≔y−x⁢z+x+y−1⁢z+1;p2≔y−x+x+y−1⁢z+1
p1≔y−x⁢z+y+x−1⁢z+1
p2≔y−x+y+x−1⁢z+1
The example is constructed in such a way that splitting is needed: modulo the first factor of my, namely y−x, the gcd is z+1, while it is constant modulo the second factor, y+x−1. Correspondingly, there are two branches.
rg:=RegularGcd⁡p1,p2,z,rc,R;
rg≔y+x−1⁢z+2⁢y−1,regular_chain,3⁢y2+−2⁢x−2⁢y−x2+2⁢x,regular_chain
Check the first case.
g1,rc1≔oprg1;eq1:=Equations⁡rc1,R;SparsePseudoRemainder⁡2⁢x+1⁢eq11,rcx,R
g1,rc1≔y+x−1⁢z+2⁢y−1,regular_chain
eq1≔2⁢x−1⁢y+x−4,x2−2
−7⁢x+7⁢y
Note that rc1 is not normalized. The SparsePseudoRemainder computation shows that it corresponds to the "modulo y−x" branch.
u:=SparsePseudoRemainder⁡g1,rc1,R;factoru
u≔−4⁢z⁢x−4⁢x+9⁢z+9
−z+1⁢4⁢x−9
This is the desired result, up to a multiplicative factor −4⁢x+9 which is a unit modulo rc1.
Check the second case. Again, the regular chain rc2 is not normalized, and the SparsePseudoRemainder computation shows that it corresponds to the "modulo y+x−1" branch.
g2,rc2≔oprg2;eq2≔Equationsrc2,R;SparsePseudoRemainder2⁢x+1⁢eq21,rcx,R
g2,rc2≔3⁢y2+−2⁢x−2⁢y−x2+2⁢x,regular_chain
eq2≔2⁢x−1⁢y−3⁢x+5,x2−2
7⁢x+7⁢y−7
Check that g2 is a unit modulo rc2. First, reduce it modulo rc2. Then ask if the result is invertible modulo rc2. The answer proves it is.
h:=SparsePseudoRemainder⁡g2,rc2,R;out:=Inverse⁡h,rc2,R;ih:=out111;SparsePseudoRemainderh⁢ih,rc2,R
h≔−72⁢x+113
out≔113+72⁢x,2401,regular_chain,
ih≔113+72⁢x
2401
2.6 Solving systems of equations incrementally
The central command of the RegularChains library is the Triangularize command. The algorithm behind this command solves systems of equations incrementally. To do this, we rely on an important operation Intersect, which computes the common part of a hypersurface and the quasi-component of a regular chain. See the help page of Intersect for a more formal description of it. Let us now illustrate how to use it to solve a polynomial system incrementally.
vars := [x, y, z];R := PolynomialRing(vars);
vars≔x,y,z
Define a set of equations.
sys := [x^2+y+z-1, x+y^2+z-1, x+y+z^2-1];
sys≔x2+y+z−1,y2+x+z−1,z2+x+y−1
Define the empty regular chain.
rc := Empty(R);
Solve the first equation.
dec := Intersect(sys[1], rc, R);map(Equations, dec, R);
dec≔regular_chain
x2+y+z−1
Solve the first and second equations.
dec := [seq(op(Intersect(sys[2], rc, R)), `in`(rc, dec))];map(Equations, dec, R);
dec≔regular_chain,regular_chain
x−y,y2+y+z−1,x+y−1,y2−y+z
Solve the three equations together.
dec := [seq(op(Intersect(sys[3], rc, R)), `in`(rc, dec))];Display(dec, R);
dec≔regular_chain,regular_chain,regular_chain,regular_chain
x−z=0y−z=0z2+2⁢z−1=0,x=0y=0z−1=0,x−1=0y=0z=0,x=0y−1=0z=0
3. Real solutions of polynomial systems
The RegularChains library offers a variety of tools to compute the real solutions of polynomial systems. A first group of commands (namely RealTriangularize, LazyTriangularize and SamplePoints) deals with arbitrary semi-algebraic systems. That is, given any system S of polynomial equations, polynomial inequations and polynomial inequalities (strict or large) these commands produce information about the real solutions of this system.
RealTriangularize returns a full description of the real solutions of S: it computes simpler systems S1,...,Se such that a point is a solution of S if and only if it is a solution of one of the systems S1,...,Se. Each of these systems
has a triangular shape and remarkable properties: for this reason it is called a regular semi-algebraic system and the set of the S1,...,Se is called a full triangular decomposition of S.
LazyRealTriangularize allows the user to compute a triangular decomposition of S in an interactive manner. This feature is particularly well adapted for systems that are hard to solve. For such systems, LazyRealTriangularize returns the components of S of maximum dimension together with unevaluated recursive calls, such that, when fully evaluated, these calls produce the other components of S (which are generally harder to compute).
SamplePoints is even a lazier (and thus much cheaper) way of solving:
it produces at least one sample point per connected component
of the solution set of S. This way of solving is often sufficient in practical problems.
A second group of commands compute the real solutions of particular
types of polynomial systems (such as systems with finitely many complex solutions or parametric systems) or provide advanced features (such as CylindricalAlgebraicDecompose, LinearSolve, Projection, Difference). All these commands except RealRootClassification and RealComprehensiveTriangularize are located in the subpackage SemiAlgebraicSetTools.
3.1 RealTriangularize: solving systems of equations, inequations and inequalities
Consider the generic equation of degree two.
R := PolynomialRing([x, c, b, a]); sys := [a*x^2+b*x+c=0];
sys≔a⁢x2+b⁢x+c=0
Compute a triangular decomposition of the 4-variable hypersurface it defines.
dec := RealTriangularize(sys, R);
dec≔regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system
Display(dec, R);
a⁢x2+b⁢x+c=0−4⁢c⁢a+b2>0anda≠0,2⁢a⁢x+b=04⁢a⁢c−b2=0a≠0,b⁢x+c=0a=0b≠0,c=0b=0a=0
Consider the record output format.
RealTriangularize(sys, R, output=record);
a⁢x2+b⁢x+c=0−4⁢c⁢a+b2>0a≠0,2⁢a⁢x+b=04⁢a⁢c−b2=0a≠0,b⁢x+c=0b≠0a=0,c=0b=0a=0
Next, we consider a system of equations, inequations and inequalities.
R := PolynomialRing([y, x, b, a]);
sys := [x^3-3*y^2*x+a*x+b=0, 3*x^2-y^2+a=0, 1-y*x>0, y<>0];
sys≔x3−3⁢y2⁢x+a⁢x+b=0,3⁢x2−y2+a=0,0<−y⁢x+1,y≠0
out := RealTriangularize(sys, R);
out≔regular_semi_algebraic_system,regular_semi_algebraic_system
Display(out, R);
y2−3⁢x2−a=08⁢x3+2⁢a⁢x−b=0−y⁢x+1>04⁢a3+27⁢b2>0and4⁢b2⁢a3−16⁢a4+27⁢b4−512⁢a2−4096≠0,x⁢y+1=02⁢a3+18⁢b2+32⁢a⁢x+−a2−48⁢b=027⁢b4+4⁢a3⁢b2−16⁢a4−512⁢a2−4096=0
Consider now an example which has finitely many complex solutions.
R := PolynomialRing([x, y, z]):
sys := [x^3 + y + z -1=0, x + y^3 + z -1=0, x + y + z^3 -1=0];
sys≔x3+y+z−1=0,y3+x+z−1=0,z3+x+y−1=0
Compute the real solutions of sys.
dec≔regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system
x−z=0y−z=0z3+2⁢z−1=0,x−1=0y+1=0z−1=0,x=0y=0z−1=0,x+1=0y−1=0z−1=0,x−1=0y=0z=0,x=0y−1=0z=0,x−1=0y−1=0z+1=0
Returning now to systems which have infinitely many complex solutions, consider now the intersection of the algebraic surfaces Sofa and Cylinder from the Algebraic Surface Gallery. As their names suggest, they are respectively the equations of a sofa and a (sort of) cylinder. One expects to find a real curve in their intersection, as we shall verify.
R := PolynomialRing([z, y, x]); Sofa := x^2 + y^3 + z^5; Cyl := x^4 + z^2 - 1;
Sofa≔z5+y3+x2
Cyl≔x4+z2−1
RealTriangularize([Sofa, Cyl], R, output=record);
x8−2⁢x4+1⁢z+y3+x2=0y6+2⁢x2⁢y3+x20−5⁢x16+10⁢x12−10⁢x8+6⁢x4−1=0x<1x+1>0x12−4⁢x8+5⁢x4−1≠0,x8−2⁢x4+1⁢z−x2=0y3+2⁢x2=0x12−4⁢x8+5⁢x4−1=0,x8−2⁢x4+1⁢z+x2=0y=0x12−4⁢x8+5⁢x4−1=0,z=0y+1=0x+1=0,z=0y+1=0x−1=0
3.2 LazyRealTriangularize: interactive solving for systems of equations, inequations and inequalities
Consider again the generic equation of degree two. Now we solve it interactively.
sys≔x2⁢a+x⁢b+c=0
Use LazyRealTriangularize to start the decomposition.
dec := LazyRealTriangularize(sys, R);
dec≔a⁢x2+b⁢x+c=00<−4⁢c⁢a+b2∧a≠0LazyRealTriangularize⁡a=0,a⁢x2+b⁢x+c=0,polynomial_ringa=0LazyRealTriangularize⁡−4⁢c⁢a+b2=0,a⁢x2+b⁢x+c=0,polynomial_ring−4⁢c⁢a+b2=0otherwise
Go one step further, computing components in lower dimension.
dec2 := value(dec);
dec2≔x2⁢a+x⁢b+c=00<−4⁢a⁢c+b2∧a≠0x⁢b+c=0,a=0b≠0LazyRealTriangularize⁡a=0,b=0,x⁢b+c=0,x2⁢a+x⁢b+c=0,polynomial_ringb=0a=02⁢a⁢x+b=0,4⁢a⁢c−b2=0a≠0LazyRealTriangularize⁡a=0,−4⁢a⁢c+b2=0,4⁢a⁢c−b2=0,2⁢a⁢x+b=0,x2⁢a+x⁢b+c=0,polynomial_ringa=0−4⁢a⁢c+b2=0otherwise
Go the last step, computing components in dimension zero.
value(dec2);
x2⁢a+x⁢b+c=00<−4⁢a⁢c+b2∧a≠0x⁢b+c=0,a=0b≠0c=0,b=0,a=0b=0a=02⁢a⁢x+b=0,4⁢a⁢c−b2=0a≠0c=0,b=0,a=0a=0−4⁢a⁢c+b2=0otherwise
If one is only interested in computing the main components, the list output format does the job.
dec := LazyRealTriangularize(sys, R, output=list);
dec≔regular_semi_algebraic_system
a⁢x2+b⁢x+c=0−4⁢c⁢a+b2>0anda≠0
Another way to conduct the computation interactively is to use the record output format.
dec := [LazyRealTriangularize(sys, R, output=record)];
dec≔a⁢x2+b⁢x+c=0−4⁢c⁢a+b2>0a≠0,LazyRealTriangularize⁡a=0,a⁢x2+b⁢x+c=0,polynomial_ring,output=record,LazyRealTriangularize⁡−4⁢c⁢a+b2=0,a⁢x2+b⁢x+c=0,polynomial_ring,output=record
Go one step further.
dec2≔a⁢x2+b⁢x+c=0−4⁢c⁢a+b2>0a≠0,b⁢x+c=0b≠0a=0,LazyRealTriangularize⁡a=0,b=0,b⁢x+c=0,a⁢x2+b⁢x+c=0,polynomial_ring,output=record,2⁢a⁢x+b=04⁢a⁢c−b2=0a≠0,LazyRealTriangularize⁡a=0,−4⁢a⁢c+b2=0,4⁢a⁢c−b2=0,2⁢a⁢x+b=0,a⁢x2+b⁢x+c=0,polynomial_ring,output=record
Go the last step.
a⁢x2+b⁢x+c=0−4⁢a⁢c+b2>0a≠0,b⁢x+c=0b≠0a=0,c=0b=0a=0,2⁢a⁢x+b=04⁢a⁢c−b2=0a≠0,c=0b=0a=0
Computing a lazy triangular decomposition is usually much less expensive than computing a full one. The following is an example.
unassign('u'); variables := [x, u, v, w]; R := PolynomialRing(variables); sys := [u*x^2+v*x+1=0, v*x^3+w*x+u=0, w*x^2+v*x+u<=0];
variables≔x,u,v,w
sys≔u⁢x2+v⁢x+1=0,v⁢x3+w⁢x+u=0,w⁢x2+v⁢x+u≤0
Computing a lazy decomposition takes than a second.
dec := LazyRealTriangularize(sys,R,output=list);
Computing a full one does not terminate within an hour.
3.3 SamplePoints: computing at least one point per connected component
Consider again the generic equation of degree two.
R := PolynomialRing([x, c, b, a]); F := [a*x^2+b*x+c=0];
F≔a⁢x2+b⁢x+c=0
Compute sample points of the 4-variable hypersurface it defines.
S := SamplePoints(F, R, output=record);
S≔x=−1c=12b=0a=−12,x=1c=12b=0a=−12,x=−1c=−12b=0a=12,x=1c=−12b=0a=12,x=0c=0b=−12a=0,x=0c=0b=12a=0,x=0c=0b=0a=0,x=0c=0b=0a=−12,x=0c=0b=0a=12
Consider the Tacnode curve. We look for sample points in the middle of the right branch.
R := PolynomialRing([y, x]); F := [y^4-2*y^3+y^2-3*x^2*y+2*x^4];
F≔2⁢x4+y4−3⁢x2⁢y−2⁢y3+y2
with(plots): implicitplot(F, x=-2..2, y=-1..3, numpoints=1000000);
SamplePoints([op(F), 2*x > 1, x < 1], R, output=record);
y=1332,105256x=34,y=237128,11964x=34
3.4 Isolating the real roots of a regular chain
Isolating real roots
Define a simple regular chain.
R := PolynomialRing([y, x]): rc := Chain([2*x^2-1, 3*y^3-x], Empty(R), R):
Isolate its real roots.
rr := RealRootIsolate(rc, R);
rr≔box,box
Display the box values.
solution := map(BoxValues, rr, R);
solution≔y=−2072707333554432,−2072706333554432,x=−4634165536,−7414551048576,y=1036353116777216,1036353716777216,x=7414551048576,4634165536
Each element of the list is called a box. Each box encodes a real root, in the sense that it contains exactly one real root of rc. The RealRootIsolate command returns all real roots of a given regular chain in this way. Thus, it is guaranteed that no root is lost. In the example, there are two real roots.
solution[1]; solution[2];
y=−2072707333554432,−2072706333554432,x=−4634165536,−7414551048576
y=1036353116777216,1036353716777216,x=7414551048576,4634165536
Thus, the first root satisfies 12<x<1 and 0<y<1, and the second one satisfies −1<x<−12 and −1<x<0.
The BoxValues command returns a list of the form v=i, where v is a variable and i is either a rational number or an open interval encoded by a list. The reason why singletons are returned is that rational solutions are sometimes hit, as in the following example.
rc := Chain([2*x-1, 3*y^3-x], Empty(R), R): rr := RealRootIsolate(rc, R): map(BoxValues, rr, R);
y=5770531048576,288527524288,x=12
The Display command prints the isolated real roots in a pretty manner.
Display(rr, R);
y=5770531048576,288527524288x=12
Choosing a precision
The isolating boxes can be as small as needed. The abserr option allows you to obtain boxes whose widths are smaller than or equal to a certain absolute precision.
rc := Chain([2*x^2-1, 3*y^3-x], Empty(R), R): rr := RealRootIsolate(rc, R, abserr = 1/10^10): map(BoxValues, rr, R);
y=−27167378515774398046511104,−1086695140626917592186044416,x=−7592501251073741824,−97184015999137438953472,y=27167378515674398046511104,27167378515774398046511104,x=97184015999137438953472,7592501251073741824
evalf(%);
y=−0.6177146705,−0.6177146705,x=−0.7071067812,−0.7071067812,y=0.6177146705,0.6177146705,x=0.7071067812,0.7071067812
In fact, this involves the algebraic numbers 12 and 12313.
evalf⁡12;evalf⁡12313;
0.7071067810
0.6177146705
3.5 Isolating and counting the real zeros of a semi-algebraic system with finitely many solutions
Recall that a semi-algebraic system (SAS) is a system containing polynomial equations, polynomial (non-strict or/and strict) inequalities, and polynomial inequations, which are denoted by F, N, P, and H, respectively. For example, the system x2+y2−1=0, x y−1=0, x≥0, y>0 is represented by
F := [x^2+y^2-1, 2*x*y-1]: N := [x]: P := [y]: H := []:
Define the polynomial ring
R := PolynomialRing([x, y]):
The RealRootIsolate command isolates all the real zeros of a given semi-algebraic system.
rr := RealRootIsolate(F, N, P, H, R); solution := Display(rr, R);
rr≔box
solution≔x=58,34y=4564,91128
The RealRootCounting command computes the number of distinct real solutions of a given semi-algebraic system.
RealRootCounting(F, N, P, H, R);
1
Consider a less trivial example.
R := PolynomialRing([z, y, x, c]): F := [1-c*x-x*y^2-x*z^2, 1-c*y-y*x^2-y*z^2, 1-c*z-z*x^2-z*y^2, 8*c^6+378*c^3-27]: N := []: P := [c, 1-c]: H := []: RealRootCounting(F, N, P, H, R);
4
If the input system has infinitely many complex solutions (that is, it is positive-dimensional over the complex numbers), RealRootCounting will return a message suggesting to call RealRootClassification instead.
R := PolynomialRing([x, y]): RealRootCounting([x^2+y^2], [], [], [], R);
Error, (in RegularChains:-SemiAlgebraicSetTools:-RealRootCounting) system is not zero-dimensional; try RealRootClassification |lib/RegularChains/src/user.mm:9796|
3.6 Partial cylindrical algebraic decomposition
The command RealRootClassification makes use of Partial Cylindrical Algebraic Decomposition (PCAD). The calling sequence is PartialCylindricalAlgebraicDecomposition(p, lp, R), where R is a polynomial ring, p is a polynomial in R, and lp is a list of polynomials in R representing positivity conditions. The output of the function is a list sp of sample points. Each sample point is represented by a list of rational numbers, as many as there are variables in R. Each inner list gives the coordinates of a sample point of a (real) open connected component of the (real) space decomposed by the equation p=0. Moreover, sample points which do not satisfy q>0 for all polynomials q ∈lp are discarded.
R := PolynomialRing([x, y, t]): PartialCylindricalAlgebraicDecomposition(y, [], R); PartialCylindricalAlgebraicDecomposition(y, [x], R);PartialCylindricalAlgebraicDecomposition(x*y, [], R);PartialCylindricalAlgebraicDecomposition(x*y, [x], R);
0,−12,0,0,12,0
12,−12,0,12,12,0
−12,−12,0,12,−12,0,−12,12,0,12,12,0
As a more advanced example, compute sample points for the polynomial system of equations sys below which in addition make each polynomial in sys positive.
R := PolynomialRing([x, y]): sys := [-x^2-y+1, x+y^2-1, -x^2+y^2]:sp≔PartialCylindricalAlgebraicDecomposition∏j=1nops⁡syssysj,sys,R
sp≔0,−178,221512,−287256,197512,1316
Check the result.
for i to nops(sp) do print(eval(sys, [x = sp[i][1], y = sp[i][2]])) end do;
258,22564,28964
507191262144,4512165536,280635262144
10343262144,23512,134247262144
Plot these sample points.
with(plots): colors := [blue, green, red, brown]: curves := seq(implicitplot(sys[i], x = -3 .. 3, y = -4 .. 3, color = colors[i], numpoints = 5000), i = 1 .. 3): points := pointplot(sp, color = colors[4]): display([curves, points]);
Compute and plot sample points for the same system sys but without any sign constraints.
sp≔PartialCylindricalAlgebraicDecomposition∏j=1nops⁡syssysj,,R: points := pointplot(sp, color = colors[4]): display([curves, points]);
3.7 Cylindrical algebraic decomposition
Cylindrical Algebraic Decomposition (CAD) is a fundamental and powerful tool for studying systems of equations, inequations and inequalities.
Our algorithm is different from the traditional algorithm of Collins. It first computes a cylindrical decomposition of the complex space, from which a CAD of the real space can be easily extracted.
Consider the hyperbola xy−1=0.
R := PolynomialRing([y, x]); F := [y*x-1];
F≔x⁢y−1
A cylindrical algebraic decomposition adapted to the polynomial xy−1 can be computed by the command CylindricalAlgebraicDecompose as follows:
outcad := CylindricalAlgebraicDecompose(F, R, output=piecewise);
outcad≔1y<1x1y=1x11x<yx<01x=01y<1x1y=1x11x<y0<x
The output CAD is described by a nested piecewise function. The outmost piecewise function is a function with three conditions x<0, x=0, and 0<x. Each of the conditions has a corresponding expression, which is again a piecewise function. The output could be read from top to bottom and from right to left.
One can see that the CAD consists of seven cells.
For example, x<0 and y<1x describes one cell of the CAD, where regular_chain, −1,−1, −2,−2
represents a sample point in this cell.
This sample point is represented by a regular chain and an isolating box such that inside this box there is one and only one root of this regular chain.
We plot the hyperbola and all the sample points of the CAD adapted to this hyperbola as follows.
with(plots): sp := [[-1, -2], [-1, -1], [-1, 0], [0, 0], [1, 0], [1, 1], [1, 2]]: points := pointplot(sp, color = blue): curve := implicitplot([x*y-1, x], x = -5 .. 5, y = -5 .. 5, color=[red, black]): display([curve, points]);
The piecewise format is good when the output has few cells. When many cells are present the 'output'='cadcell' and 'output'='rootof' formats are useful.
R := PolynomialRing([x, c, b, a]); F := [a*x^2+b*x+c]; cad := CylindricalAlgebraicDecompose(F, R, output = cadcell);
F≔x2⁢a+x⁢b+c
cad≔cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell
nops(cad);
27
The output consists of 27 cells, which can also been displayed as so-called Taski Formulas.
Display(cad, R);
x=xc<b24⁢ab=ba<0,x<−b2⁢ac=b24⁢ab=ba<0,x=−b2⁢ac=b24⁢ab=ba<0,−b2⁢a<xc=b24⁢ab=ba<0,x<−b+−4⁢c⁢a+b22⁢ab24⁢a<cb=ba<0,x=−b+−4⁢c⁢a+b22⁢ab24⁢a<cb=ba<0,−b+−4⁢c⁢a+b22⁢a<x∧x<−b+−4⁢c⁢a+b22⁢ab24⁢a<cb=ba<0,x=−b+−4⁢c⁢a+b22⁢ab24⁢a<cb=ba<0,−b+−4⁢c⁢a+b22⁢a<xb24⁢a<cb=ba<0,x<−cbc=cb<0a=0,x=−cbc=cb<0a=0,−cb<xc=cb<0a=0,x=xc<0b=0a=0,x=xc=0b=0a=0,x=x0<cb=0a=0,x<−cbc=c0<ba=0,x=−cbc=c0<ba=0,−cb<xc=c0<ba=0,x<−b+−4⁢c⁢a+b22⁢ac<b24⁢ab=b0<a,x=−b+−4⁢c⁢a+b22⁢ac<b24⁢ab=b0<a,−b+−4⁢c⁢a+b22⁢a<x∧x<−b+−4⁢c⁢a+b22⁢ac<b24⁢ab=b0<a,x=−b+−4⁢c⁢a+b22⁢ac<b24⁢ab=b0<a,−b+−4⁢c⁢a+b22⁢a<xc<b24⁢ab=b0<a,x<−b2⁢ac=b24⁢ab=b0<a,x=−b2⁢ac=b24⁢ab=b0<a,−b2⁢a<xc=b24⁢ab=b0<a,x=xb24⁢a<cb=b0<a
Another important feature of the CAD command is the fact that it can take a list of semi-algebraic systems as input. This list of semi-algebraic systems represents a DNF quantifier free formula, that is, a disjunction of semi-algebraic systems.
Consider the union of a circle and a line.
Circle := x^2+y^2-1=0; Line := x-2=0; with(plots): implicitplot([Circle, Line], x = -1 .. 3, y = -1 .. 2, color=[red, blue]);
Circle≔x2+y2−1=0
Line≔x−2=0
Compute a CAD of the union of Circle and Line.
R := PolynomialRing([y, x]); cad := CylindricalAlgebraicDecompose([[Circle], [Line]], R, output=cadcell);
cad≔cad_cell,cad_cell,cad_cell,cad_cell,cad_cell
y=0x=−1,y=−−x2+1−1<x∧x<1,y=−x2+1−1<x∧x<1,y=0x=1,y=yx=2
Each cad_cell has a sample point associated with it.
sp := map(SamplePoints, cad, R): Display(sp,R);
y=0x=−1,y=−1x=0,y=1x=0,y=0x=1,y=0x=2
Last but not least, the CAD command is back engine of SolveTools:-SemiAlgebraic.
SolveTools:-SemiAlgebraic([x^2+x-c>0], [c, x]);
c<−14,x=x,c=−14,x≠−12,−14<c,x<−12−4⁢c+12,−14<c,−12+4⁢c+12<x
cad := CylindricalAlgebraicDecompose([[x^2+x-c>0]], PolynomialRing([x, c]), output=rootof);
cad≔c<−14,x=x,c=−14,x≠−12,−14<c,x<−12−4⁢c+12,−14<c,−12+4⁢c+12<x
3.8 Solving a linear semi-algebraic system
The input linear semi-algebraic system:
S := [f00 = c, f10 = c + cx1, f01 = c + cx2, f11 = c + cx1 + cx2 + cx1x2, cx1x2 <= 0];
S≔f00=c,f10=c+cx1,f01=c+cx2,f11=c+cx1+cx2+cx1x2,cx1x2≤0
Define the elimination order (descending order).
R := PolynomialRing([cx1x2, cx1, cx2, c, f00, f01, f10, f11]):
Call LinearSolve to eliminate the variables.
The output is a set of equivalent linear equations and inequalities sorted in ascending order according to the largest variables appearing in the constraints. It provides conditions on lower order variables such that higher order variables having solutions.
In other words, the projection of the solutions of input system S onto any lower dimensional space, say the space formed by the smallest i variables, are exactly the solutions of those constraints in the output which only involve the smallest i smallest variables.
R := PolynomialRing([cx1x2, cx1, cx2, c, f00, f01, f10, f11]): result := LinearSolve(S, R);
result≔f00≤−f11+f10+f01,c=f00,cx2=f01−f00,cx1=f10−f00,cx1x2=f11−f10−f01+f00
3.9 Verifying the output of different real solvers
On a given input polynomial system, two solving tools may produce correct results that look fairly different. Proving that these two results, say S1 and S2, are equivalent can be a very complex task. Here’s an example.
Given a triangle with edges a, b, c (denoting the respective lengths by a, b,c as well) the following two conditions C1, C2 are both characterizing the fact that the external bisector of the angle of a, c intersects with b on the other side of a than the triangle:
We set S1 and S2 up first. S1 is the disjunction of C1 and C2.
C1:=[a > 0 , b > 0 , c > 0 , a < b + c , b < a + c , c < a + b, b^2 + a^2 - c^2 <= 0 ]; C2:=[a > 0 , b > 0 , c > 0 , a < b + c , b < a + c , c < a + b, c*(b^2 + a^2 - c^2)^2 < a*b^2*(2*a*c - (c^2 + a^2 - b^2))]: S1:=[C1, C2]; S2 := [a-c<0, a > 0 , b > 0 , c > 0 , a < b + c , b < a + c , c < a + b];
C1≔0<a,0<b,0<c,a<b+c,b<a+c,c<a+b,a2+b2−c2≤0
S1≔0<a,0<b,0<c,a<b+c,b<a+c,c<a+b,a2+b2−c2≤0,0<a,0<b,0<c,a<b+c,b<a+c,c<a+b,c⁢a2+b2−c22<a⁢b2⁢−a2+2⁢c⁢a+b2−c2
S2≔a−c<0,0<a,0<b,0<c,a<b+c,b<a+c,c<a+b
Compute regular semi-algebraic system representations dec1 (resp. dec2) for S1 (resp. S2).
R := PolynomialRing([a,b,c]): dec1 := map(op, map(RealTriangularize, S1,R)); dec2:= RealTriangularize(S2, R);
dec1≔regular_semi_algebraic_system,regular_semi_algebraic_system,regular_semi_algebraic_system
dec2≔regular_semi_algebraic_system
Compute the differences: S1 \ S2 and S2 \ S1.
Difference(dec1,dec2,R);
Difference(dec2,dec1,R);
3.10 Computing the projection of a semi-algebraic set
In the following problem, we are interesting in determining sufficient and necessary conditions on the variables a1, a2, for the prescribed semi-algebraic system to have solutions in r1, r2, x1, x2, e1, e2. This question is equivalent to compute the standard projection of the corresponding semi-algebraic set on the (a1, a2)-plane.
Problem: ∃(r1, r2, x1, x2, e1, e2) (∧f ∈ eqsf=0 ∧p∈ piep>0 )
vars := [r1, r2, x1, x2, e1, e2, a1, a2]; eqs := [ r1^2 - r2^2 - e1^2 + e2^2 + x1^2 - 2*x1*x2 + x2^2, 2*r1*r2 - 2*e1*e2, -r1 + e1 + x1*a2 - x2*a2, -r2 + e2 - x1*a1 + x2*a1, r1^2 + r2^2 + x1^2 + x2^2 + e1^2 + e2^2 - 1]; pie := [r1, -e1]; ineqs := []; nie := []; params := [a1,a2]; R := PolynomialRing(vars): proj := Projection(eqs, nie, pie, ineqs, 2, R);
vars≔r1,r2,x1,x2,e1,e2,a1,a2
eqs≔−e12+e22+r12−r22+x12−2⁢x1⁢x2+x22,−2⁢e1⁢e2+2⁢r1⁢r2,x1⁢a2−x2⁢a2+e1−r1,−x1⁢a1+x2⁢a1+e2−r2,e12+e22+r12+r22+x12+x22−1
pie≔r1,−e1
ineqs≔
nie≔
params≔a1,a2
proj≔regular_semi_algebraic_system,regular_semi_algebraic_system
Show the result:
Display(proj, R);
a1=0a2<−1ora2−1>0,a12+a22−1>0anda1≠0anda2≠0
4. Linear algebra over towers of (field) extensions
Regular chains encode towers of transcendental and algebraic extensions of the base field. In practice, these towers themselves are not always fields and may have zero-divisors. Many standard algorithms (for example, for solving systems of linear equations) require that the coefficient ring be a field. This difficulty is overcome by means of the so-called D5 Principle. This principle is at the core of the theory of regular chains and allows us to generalize many algorithms which are a priori restricted to coefficients from a field.
The MatrixTools submodule applies the D5 Principle to algorithms for solving linear systems with coefficient rings encoded by regular chains. Below, use of this submodule is demonstrated by two examples. As discussed earlier regarding polynomial gcd computations, splitting naturally occurs when computing modulo regular chains. Sometimes, split results can be recombined as illustrated below.
4.1 Automatic case discussion and recombination (I)
Assume that there are two algebraic entities, y and z; that they have the same square; and that z is a4th root of −1. Suppose you need to perform algebraic computations with y and z.
R := PolynomialRing([y, z]): rc := Chain([z^4+1, y^2-z^2], Empty(R), R): Equations(rc, R);
y2−z2,z4+1
For example, you may want to compute the inverse of the following matrix.
A≔1y+z0y−z:
Clearly, the result depends on whether y and z are equal or not. Note that from the assumptions above, neither y=z nor y=−z can be deduced. When y≠z, the matrix A has an inverse. When they are equal, the matrix A is singular. These facts are detected automatically by the command MatrixInverse.
result := MatrixInverse(A, rc, R);
result≔100z32,regular_chain,noInv,1y+z0y−z,regular_chain
Check the first result. Note the use of the command MatrixMultiply in order to multiply two matrices modulo a regular chain.
B,rc1≔opresult11;Equationsrc1,R;MatrixMultiply⁡B,A,rc1,R
B,rc1≔100z32,regular_chain
y+z,z4+1
1001
rc2≔result213;Equations⁡rc2,R;
rc2≔regular_chain
y−z,z4+1
You can see that the computation (and the regular chain) was split into two branches. The first one corresponds to y+z=0, and in that branch the matrix is invertible. The second branch corresponds to y=z, and in that branch the matrix is not invertible.
Consider the matrix M below and compute its inverse modulo the regular chain rc. Here again, computations split. However, the matrix M is invertible in both cases.
M := Matrix([[1, y+z], [2, y-z]]); result := MatrixInverse(M, rc, R);
M≔1y+z2y−z
result≔10−z3z32,regular_chain,012−z32z34,regular_chain,
Double check this result.
op(result[1][1]);
10−z3z32,regular_chain
unassign'N';N1 ,rc1≔opresult11;Equations⁡rc1,R;N1;MatrixMultiplyN1,M,rc1,R
N1,rc1≔10−z3z32,regular_chain
10−z3z32
N2,rc2≔opresult12;Equationsrc2,R;MatrixMultiplyN2,M,rc2,R
N2,rc2≔012−z32z34,regular_chain
Since the matrix M is invertible in both branches given by the regular chains rc1 and rc2, it is natural to ask whether there is a "generic" answer that would hold for both cases. The answer is yes. Technically speaking, one can observe that the Chinese Remainder Theorem applies since the (saturated) ideals of rc1 and rc2 are relatively prime. The command MatrixCombine implements this recombination.
combined:=MatrixCombine⁡rc1,rc2,R,N1,N2
combined≔y⁢z32+12−y⁢z34+1414⁢y⁢z2−34⁢z3−18⁢y⁢z2+38⁢z3,regular_chain
Check that the above matrix times M gives the identity matrix modulo rc.
MatrixMultiply(combined[1][1], M, combined[1][2], R);
4.2 Automatic case discussion and recombination (II)
Can there be several cases in the output of the command MatrixCombine? In other words, is it possible that this command fails recombining several cases into one, even if the Chinese Remainder Theorem applies? Yes, this can happen, for algebraic reasons that shall be explained below. For starters, consider one of the previous polynomial systems.
sys := {x+y+z^2-1, x+y^2+z-1, x^2+y+z-1}: R := PolynomialRing([x, y, z]): l := Triangularize(sys, R, normalized = yes); map(Equations, l, R);
Next, generate four random 2×2 matrices with polynomial entries.
A := [seq(Matrix([seq([seq(randpoly([x, y, z], degree = 1), j = 1 .. 2)], i = 1 .. 2)]), k = 1 .. 4)];
A≔−20⁢x+51⁢y−87⁢z−372⁢x+94⁢y+70⁢z+7385⁢x+21⁢y+51⁢z−610⁢x−16⁢y−95⁢z−16,−69⁢x−53⁢y−53⁢z+65−45⁢x−54⁢y+11⁢z+38−29⁢x−27⁢y−95⁢z−3993⁢x+55⁢y+65⁢z+23,−71⁢x+86⁢y+77⁢z+4536⁢x−15⁢y+64⁢z+7699⁢x+80⁢y+77⁢z+3640⁢x+6⁢y+92⁢z+38,7⁢x+97⁢y+68⁢z−58−54⁢x−6⁢y+63⁢z+4721⁢x+4⁢y+43⁢z−16−81⁢x+93⁢y+93⁢z−84
Attempt the recombination of the four cases given by the regular chains in A, and observe that MatrixCombine produces two cases.
combined := MatrixCombine(l, R, A);
combined≔182⁢y−5168⁢y−7111⁢y+5209⁢y−165,regular_chain,1052⁢z2+49⁢z−1792−95⁢z2−24⁢z+168−2852⁢z2−128⁢z+27322052⁢z2+104⁢z−2372,regular_chain
Now investigate why these two cases cannot be merged into a single one.
rc1≔combined12:Equationsrc1,R;rc2≔combined22:Equations⁡rc2,R
x+y−1,y2−y,z
2⁢x+z2−1,2⁢y+z2−1,z3+z2−3⁢z+1
The two ideals generated by rc1 and rc2 are obviously relatively prime (no common roots in z). Thus, the Chinese Remainder Theorem applies. But, if you try to recombine rc1 and rc2 into a single system, this will create a polynomial in y with a zero-divisor as a leading coefficient, as seen below. This is forbidden by the properties of a regular chain.
First, create two new regular chains with the polynomials from rc1 and rc2 that are univariate in the variable z.
S≔PolynomialRingz:rc3≔Chainz,EmptyS,S:rc4≔Chainz3+z2−3⁢z+1,EmptyS,S:
Then define two 1×1 matrices U1,U2, and combine them with regards to rc3 and rc4.
U1≔Matrixy2−y;U2≔Matrix2⁢y+z2−1;combined ≔MatrixCombinerc3,rc4,S,U1,U2;V,rc5≔opcombined1:Equationsrc5,S
U1≔y2−y
U2≔2⁢y+z2−1
combined≔y2⁢z3+y2⁢z2−3⁢y⁢z3−3⁢y2⁢z−3⁢y⁢z2+z3+y2+9⁢y⁢z+2⁢z2−y−3⁢z,regular_chain
z4+z3−3⁢z2+z
So, the recombination is successful. However, the initial p (with regards to z) of the resulting polynomial is a zero divisor: it vanishes modulo rc4 and is invertible modulo rc3. Consequently, the computation of the inverse using the command Inverse splits the combined regular chain rc5.
p≔InitialV1,1,R;inverse≔Inversep,rc5,S;Equations⁡inverse113,S;mapEquations,inverse2,S
p≔z3+z2−3⁢z+1
inverse≔1,1,regular_chain,regular_chain,regular_chain
z−1,z2+2⁢z−1
5. Constructible sets and rational maps
Constructible sets are the geometrical objects naturally attached to triangular decompositions as polynomial ideals are the algebraic concept underlying the computation of Gröbner bases. This relation becomes even more complex and essential in the case of polynomial systems with infinitely many solutions. Basically, constructible sets are what you get when you take algebraic varieties (defined by polynomial ideals) and add the operation of taking complements. More precisely, a constructible set is either a set of points defined by both equations and inequalities, or a finite union of such sets. Note that, in general, the complement of an algebraic variety cannot be described by a polynomial ideal, but it is a constructible set. Constructible sets have the nice property that they are closed under intersections and finite unions, like polynomial ideals, and additionally under complements. This section presents the ConstructibleSetTools submodule of the RegularChains library. To our knowledge, this is the first general-purpose computer algebra package providing constructible set as a type and exporting a rich collection of operations for manipulating constructible sets. Besides, this module provides routines in support of solving parametric polynomial systems, and several of its commands will be demonstrated in other parts of this document. The examples of the present section illustrate the Theorem of Chevalley which states that the image of a constructible set by a rational map is a constructible set.
5.1 Some high-school examples
Constructible sets appear naturally in many elementary questions from high-school problems. A simple one is the following: for which values of x does fx,y=0 have solutions, with f as below?
R≔PolynomialRingy,x: f≔1−x⋅y:
The answer is whenever x≠0 holds. Formally speaking, what we want there is the projection onto the x-axis of the hyperbola f=0. This object is not the zero set of a system of polynomial equations, and therefore it cannot be computed directly via traditional techniques such as a Gröbner basis computation. It requires some finer and more geometrical elimination process. The function Projection implements such a process via triangular decompositions. The output is an object of type constructible_set. Its internal representation is given by a list of so called regular systems.
cs:=Projection⁡f,1,R;l≔RepresentingRegularSystemscs,R;rs≔l1:
cs≔constructible_set
l≔regular_system
Each regular system is a pair consisting of a regular chain plus one or more inequations:
rc≔ConstructibleSetToolsRepresentingChainrs,R;IsEmptyChainrc,R;map`≠`,RepresentingInequationsrs,R, 0
true
x≠0
In this example, this regular chain rc is just the empty one and the inequation is just x≠0. This output may look more complicated than the posed problem itself. So, consider another familiar example but less trivial example: for which values of a, b, c does the equation a x2+b x+c=0 have solutions? This can be seen as another "projection" question.
R:=PolynomialRing⁡x,a,b,c;f:=a⁢x2+b⁢x+c;cs≔Projectionf,3,R;RepresentingRegularSystemscs,R;Displaycs,R;
f≔x2⁢a+x⁢b+c
regular_system,regular_system,regular_system
a≠0,a=0b≠0,a=0b=0c=0
We obtain three regular systems: (1) a≠0, (2) a=0,b≠0, (3) a=b=c=0.
5.2 Polynomial map images
The following picture illustrates a polynomial map Π:ℂ2→ℂ3. The task is to describe the image of this map in ℂ3. As one can see from the picture, a point with coordinates x,y,z=0,b,0, where b≠0, cannot be in the image of Π, whereas any other point with z=0 is. For this reason, the image of Π is a constructible set and not the zero set of a system of polynomial equations. The command PolynomialMapImage below computes the image of Π.
unassign'u','v';S≔PolynomialRingu,v:T≔PolynomialRingx,y,z:
After specifying the coordinates of the source space S and target space T, the polynomial map is defined and its image is computed.
Π≔u,u⁢v,0;cs≔PolynomialMapImage,Π,S,T;
Π≔u,u⁢v,0
The constructible set cs is given by a list of two regular systems. The first one is given by z=0≠x, and the second one by x=y=z=0.
lrs:=RepresentingRegularSystems⁡cs,T;map⁡Display,lrs,T
lrs≔regular_system,regular_system
z=0x≠0,x=0y=0z=0
5.3 Rational map images
Images (and pre-images) of constructible sets under rational maps are also supported by the ConstructibleSetTools submodule. To demonstrate this facility, consider the implicit equation of a curve (namely the tacnode curve) given by a parametric representation involving rational functions. The parametrization of this curve can be seen as a rational map; its one-dimensional source space S, its two-dimensional target space T, and the image ρ of an arbitrary point are defined below.
S:=PolynomialRing⁡t:T:=PolynomialRingx,y:ρ≔t3−6⁢t2+9⁢t−22⁢t4−16⁢t3+40⁢t2−32⁢t+9,t2−4⁢t+42⁢t4−16⁢t3+40⁢t2−32⁢t+9:
Here is a parametric plot of the tacnode curve.
plot⁡op⁡ρ,t=−10..10;
The parametric explicit representation of a curve is very useful for plotting it. However, in order to answer questions such as "does a given point in target space lie on the curve?", an implicit representation is more useful. The image of the full one-dimensional space under the rational map ρ is computed below.
F:=:cs1≔RationalMapImageF,ρ,S,T;l≔RepresentingRegularSystemscs1,T;Displaycs1,T;
cs1≔constructible_set
l≔regular_system,regular_system,regular_system
2⁢x4−3⁢y⁢x2+y4−2⁢y3+y2=010⁢y⁢x2+2⁢y3+2⁢x2−y2−y≠0964⁢x2⁢y6−88⁢y8−480⁢x2⁢y5+2104⁢y7−6858⁢x2⁢y4−2316⁢y6−4328⁢y3⁢x2−943⁢y5−888⁢y2⁢x2+892⁢y4−72⁢y⁢x2+318⁢y3−2⁢x2+32⁢y2+y≠0y≠0,x=0y−1=0,x=0y=0
The result has three components. The second and third ones correspond to the self-intersection points of the tacnode curve, that is, its singularities. The first component l1 defines all the other points. The role of its inequations is to exclude the two self-intersection points, so that the sets described by the three components are disjoint.
rc≔ConstructibleSetToolsRepresentingChainl1,T:eq≔Equationsrc,T;ineq≔ConstructibleSetToolsRepresentingInequationsl1,T
eq≔2⁢x4−3⁢y⁢x2+y4−2⁢y3+y2
ineq≔y,10⁢y⁢x2+2⁢y3+2⁢x2−y2−y,964⁢x2⁢y6−88⁢y8−480⁢x2⁢y5+2104⁢y7−6858⁢x2⁢y4−2316⁢y6−4328⁢y3⁢x2−943⁢y5−888⁢y2⁢x2+892⁢y4−72⁢y⁢x2+318⁢y3−2⁢x2+32⁢y2+y
The computations below show that the solution set of the equations of the first component l1 correspond to the entire tacnode curve. Note the use of the command IsContained which decides whether a constructible set is contained in another.
cs2≔GeneralConstructeq,,T;IsContainedcs1,cs2,TandIsContainedcs2,cs1,T
cs2≔constructible_set
Therefore, 2⁢x4−3⁢y⁢x2+y2−2⁢y3+y4=0 is the implicit representation of the tacnode curve.
6. Parametric polynomial systems
The ParametricSystemTools module is devoted to solving systems with parameters, including real root classification and complex root classification of such systems, as demonstrated below. The first two examples are dedicated to the complex solutions of parametric polynomial systems. The last, but very detailed, third subsection deals with the real case.
6.1 An example from classical invariant theory
Each of the following polynomials defines an elliptic curve in the complex plane. They depend on parameters a1 and a2, respectively. In invariant theory, a classical question is whether there exists a linear fractional map from the first curve to the second one.
f1≔y2−x3−a1⁢x−1;f2≔y2−x3−a2⁢x−1
f1≔−x3−a1⁢x+y2−1
f2≔−x3−a2⁢x+y2−1
These two curves are plotted below for a1=1 and a2=4.
withplots:display⁡(implicitplot⁡(f1a1=1|f1a1=1,x=−3..3,y=−3..3),implicitplot⁡(f2a2=4|f2a2=4,x=−3..3,y=−3..3,color=blue))
A generic linear fractional map is applied to the coordinates x and y of the second curve.
unassign⁡'A','B','C','E','F', 'H':f3≔evalf2,x=A⁢x+B⁢y+CG⁢x+H⁢y+K,y=D⁢x+E⁢y+FG⁢x+H⁢y+K
f3≔−A⁢x+B⁢y+C3G⁢x+H⁢y+K3−A⁢x+B⁢y+C⁢a2G⁢x+H⁢y+K+D⁢x+E⁢y+F2G⁢x+H⁢y+K2−1
Next, one stipulates that the rational function f1−f3 must be identically zero. This yields a system of equations sys. Without loss of generality, one can assume that the origin is mapped to the origin, which implies C=F=0.
sys:=coeffs⁡numer⁡f1−f3,x,y,C,F;R:=PolynomialRing⁡B,E,H,A,D,G,K,F,C,a1,a2:
sys≔−G3,−3⁢G2⁢H,−3⁢G2⁢K,−3⁢G⁢H2,−6⁢G⁢H⁢K,−G3⁢a1−3⁢G⁢K2,−H3,G3−3⁢H2⁢K,−3⁢G2⁢H⁢a1−3⁢H⁢K2,A⁢G2⁢a2−3⁢G2⁢K⁢a1+A3−D2⁢G−K3,3⁢G2⁢H,−3⁢G⁢H2⁢a1+3⁢G2⁢K,2⁢A⁢G⁢H⁢a2+B⁢G2⁢a2−6⁢G⁢H⁢K⁢a1+3⁢A2⁢B−D2⁢H−2⁢D⁢E⁢G,2⁢A⁢G⁢K⁢a2+C⁢G2⁢a2−3⁢G⁢K2⁢a1+3⁢A2⁢C−D2⁢K−2⁢D⁢F⁢G,3⁢G⁢H2,−H3⁢a1+6⁢G⁢H⁢K,A⁢H2⁢a2+2⁢B⁢G⁢H⁢a2−3⁢H2⁢K⁢a1+3⁢A⁢B2−2⁢D⁢E⁢H−E2⁢G+3⁢G⁢K2,2⁢A⁢H⁢K⁢a2+2⁢B⁢G⁢K⁢a2+2⁢C⁢G⁢H⁢a2−3⁢H⁢K2⁢a1+6⁢A⁢B⁢C−2⁢D⁢E⁢K−2⁢D⁢F⁢H−2⁢E⁢F⁢G,A⁢K2⁢a2+2⁢C⁢G⁢K⁢a2−K3⁢a1+3⁢A⁢C2−2⁢D⁢F⁢K−F2⁢G,H3,3⁢H2⁢K,B⁢H2⁢a2+B3−E2⁢H+3⁢H⁢K2,2⁢B⁢H⁢K⁢a2+C⁢H2⁢a2+3⁢B2⁢C−E2⁢K−2⁢E⁢F⁢H+K3,B⁢K2⁢a2+2⁢C⁢H⁢K⁢a2+3⁢B⁢C2−2⁢E⁢F⁢K−F2⁢H,C⁢K2⁢a2+C3−F2⁢K,C,F
To the system of equations sys, inequation constraints need to be added. Indeed, the unknowns G, H, and K cannot vanish simultaneously. Hence, the system to be solved consists of the zeros of sys, which are not common zeros of these three polynomials. This new system is easily expressed as the set-theoretical difference of two constructible sets.
cs1≔GeneralConstructsys,,R:cs2≔GeneralConstructG,H,K,,R:cs3≔Differencecs1,cs2,R:Display⁡cs3,R
B=0E−K=0H=0a2⁢A−K⁢a1=0D=0G=0F=0C=0a12+a2⁢a1+a22=0K≠0a2≠0,B=0E+K=0H=0a2⁢A−K⁢a1=0D=0G=0F=0C=0a12+a2⁢a1+a22=0K≠0a2≠0,B=0E−K=0H=0A−K=0D=0G=0F=0C=0a1−a2=0K≠0,B=0E+K=0H=0A−K=0D=0G=0F=0C=0a1−a2=0K≠0,B=0E−K=0H=0A2+K⁢A+K2=0D=0G=0F=0C=0a1=0a2=0K≠0,B=0E+K=0H=0A2+K⁢A+K2=0D=0G=0F=0C=0a1=0a2=0K≠0
The question can now be stated in algebraic terms: for which values of the parameters a1 and a2 is the constructible set non-empty? Formulas solving for the unknowns are also desired. The command ComprehensiveTriangularize addresses these two requirements. The second argument, 2 in the example below, specifies that the last two indeterminates of the polynomial ring (that is, a1 and a2) are the parameters of the system.
ct:=ComprehensiveTriangularize⁡cs3,2,R
ct≔regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,constructible_set,3,6,4,5,constructible_set,3,4,constructible_set,1,2
The second list returned by this command is a finite partition of the projection of cs onto the parameter space. Each component P of this partition is a constructible set above which the geometrical properties of cs (degree, dimension, etc.) are essentially constant; the corresponding component of cs3 is given by the regular systems of ct whose indices are associated with P. Below, the three parts of this partition are joined into a single constructible set.
d := map2(op, 1, ct[2]): d := Union(d[1], Union(d[2], d[3], R), R): Display(d, R);
a1=0a2=0,a1−a2=0a2≠0,a12+a2⁢a1+a22=0a2≠0
Next, check if the answer to the question is the one that is well-known from invariant theory, namely that the two curves can be matched provided that a13=a23.
e:=GeneralConstruct⁡a13−a23,,R;`and`IsContained⁡d,e,R,IsContained⁡e,d,R
e≔constructible_set
Finally, the three regular systems (from the first list returned by ComprehensiveTriangularize) are displayed below.
for i to 3 do Display(ct[1][i], R); end do;
B=0E−K=0H=0a2⁢A−K⁢a1=0D=0G=0F=0C=0a12+a2⁢a1+a22=0K≠0a2≠0
B=0E+K=0H=0a2⁢A−K⁢a1=0D=0G=0F=0C=0a12+a2⁢a1+a22=0K≠0a2≠0
B=0E−K=0H=0A−K=0D=0G=0F=0C=0a1−a2=0K≠0
6.2 Counting complex solutions
In this short example, it is shown how to determine the number of distinct roots of a generic polynomial equation of degree 4 depending on the parameters a, b, c, d.
unassign('a', 'b', 'c', 'd'): R := PolynomialRing([x, a, b, c, d]): p := a*x^4+b*x^2+c*x+d;
p≔a⁢x4+b⁢x2+c⁢x+d
The command ComplexRootClassification is precisely adapted to this purpose. It determines the number of distinct complex solutions of a parametric system (possibly a parametric constructible set) depending on parameters. The second argument, 4 in the example below, indicates that the last four variables of the polynomial ring, a,b,c,d, are the parameters of the equation.
cr := ComplexRootClassification([p], 4, R);
cr≔constructible_set,1,constructible_set,2,constructible_set,3,constructible_set,4,constructible_set,∞
The result is a partition of the parameter space into five sets: those parameter values for which p has exactly 1,2,3, or 4 complex roots, respectively, and those parameter values for which p has infinitely many roots (which happens only if a=b=c=d=0). Suppose you are interested in the case of three distinct roots. Display the equations and inequations of the regular systems defining the constructible set, giving the necessary and sufficient conditions for the polynomial p to have three distinct complex roots.
Info(cr[3][1], R);
256⁢d3⁢a2+−128⁢d2⁢b2+144⁢c2⁢d⁢b−27⁢c4⁢a+16⁢b4⁢d−4⁢b3⁢c2,d,a,8⁢d⁢b−9⁢c2⁢a−2⁢b3,c,32⁢d⁢b−9⁢c2,1073741824⁢b10⁢d10−66437775360⁢b9⁢c2⁢d9+672682475520⁢b8⁢c4⁢d8−2623461654528⁢c6⁢d7⁢b7+5164940132352⁢c8⁢d6⁢b6−5810557648896⁢c10⁢d5⁢b5+3961743851520⁢c12⁢d4⁢b4−1665238487040⁢c14⁢d3⁢b3+421513492032⁢c16⁢d2⁢b2−58887914328⁢c18⁢d⁢b+3486784401⁢c20⁢a−268435456⁢b12⁢d9+12683575296⁢b11⁢c2⁢d8−98524200960⁢b10⁢c4⁢d7+294298583040⁢b9⁢c6⁢d6−439871275008⁢b8⁢c8⁢d5+368924295168⁢b7⁢c10⁢d4−181579926528⁢b6⁢c12⁢d3+52038702720⁢b5⁢c14⁢d2−8035387920⁢b4⁢c16⁢d+516560652⁢b3⁢c18,27⁢c2⁢a+4⁢b3,d,c,b,c,d,b,a
This output is to be interpreted as follows. There are three cases:
c=d=0 and a≠0≠b. In this case, the polynomial degenerates to p=a x4+bx2, and the three roots are a double root at x=0 and two distinct simple roots at ±−ba.
4 b3+27 a c2=0=d and b≠0 ≠c. In this case, the polynomial degenerates to p=a x4+b x2+c x, which has x=0 as a simple root. The expression 4 b3+27 a c2 is the discriminant of the cofactor px=a x3+b x+c, and the condition that it must be zero implies that this polynomial has at least a double root. Finally, the condition b≠0 ensures that the latter polynomial does not have a triple root, that is, it has one double and one single root.
256⁢d3⁢a2+−128⁢d2⁢b2+144⁢d⁢c2⁢b−27⁢c4⁢a+16⁢d⁢b4−4⁢c2⁢b3=0 and none of the polynomials in the last list are zero, including a≠0, c≠0, d≠0, 32 b d−9 c2≠0, and 2 b3−8 b d−9 c2a≠0. The first polynomial is a factor of the discriminant of p:
discrim(p, x);
a⁢256⁢d3⁢a2−128⁢a⁢b2⁢d2+144⁢a⁢b⁢c2⁢d−27⁢a⁢c4+16⁢b4⁢d−4⁢b3⁢c2
The condition that it must be zero implies that p has at least a double root, and the remaining inequations ensure that all the other roots are simple.
6.3 Real root classification and border polynomial
Real root classification
A semi-algebraic system (SAS) is a polynomial system containing polynomial equations p=0, inequations p≠0, and inequalities p>0 or p≥0. If a semi-algebraic system contains parameters, it is called a parametric SAS. For a parametric SAS and a prescribed non-negative integer n, the real root classification problem is to compute conditions on the parameters such that the system has exactly n distinct real solutions. In the RegularChains package, a semi-algebraic system is given by four lists F, N, P, H of polynomials, representing the equations, non-negativity conditions (weak inequalities), positivity conditions (strict inequalities), and equations, respectively. The RealRootClassification command takes these four lists as the first four arguments. As in the examples above, the fifth argument, d, is an integer specifying that the last d indeterminates of the underlying polynomial ring are the parameters of the system. The sixth argument, n, specifies the desired number of distinct real solutions, and the last argument is the polynomial ring R. For example,
R := PolynomialRing([x, a, b, c]): F := [x^2*a+x*b+c]: N := []:P := [x]:H := [a]: rr := RealRootClassification(F, N, P, H, 3, 2, R);
rr≔regular_semi_algebraic_set,border_polynomial
Here, a, b, c are viewed as parameters and the task is to find conditions for the general polynomial of degree 2 to have exactly 2 distinct positive real solutions.
The output is a list, rr1 of regular semi-algebraic sets and a border polynomial object (BP), rr2; together these describe a first-order logic formula. More precisely, the list rr1 gives necessary and sufficient conditions for the input system to have the prescribed number of real solutions, provided that the condition encoded by the BP holds. The role of the border polynomial is to exclude degenerate cases, which can be handled later with further computations (more on this later).
The command below shows the contents of the BP, which is actually a list of polynomials. The logical condition encoded by the BP is that none of those polynomials should be zero.
Info(rr[2], R);
a,b,c,−4⁢a⁢c+b2
The following commands extract information about the list of regular SAS and display the logical condition that these encode, using the command Display.
ss := rr[1][1]; Display(ss, R);
ss≔regular_semi_algebraic_set
c<0anda<0andb>0and4⁢a⁢c−b2<0orc>0anda>0andb<0and4⁢a⁢c−b2<0
The output of the last command is to be interpreted as the logical disjunction ("or") of the conditions in the last two rows; each row represents the logical conjunction ("and") of the individual inequalities.
As a first approximation, a regular SAS is a subset of the real solutions of a regular chain. More precisely, it is encoded by three pieces of data:
a quantifier free formula qf,
a regular chain rc, and
a list of lists of indices l.
This encoding is called a parametric box. The formula qf specifies the conditions on the variables which are free in rc (non-algebraic), whereas rc and l specify the conditions on the variables which are algebraic in rc.
In the example above, rc and l are empty (which is often the case); therefore, the conditions encoded by the parametric box are just the ones of qf.
rc := RepresentingChain(ss, R); Equations(rc, R); box := RepresentingBox(ss); l := RepresentingRootIndex(box);
box≔parametric_box
l≔
Summarizing, the answer to the particular question is: provided that the BP holds, the input SAS has exactly 2 distinct positive real solutions if and only if qf holds. Note that, in the example, the conditions of qf imply those of the BP; thus the answer can be simplified further as follows:
the input SAS has exactly 2 distinct positive real solutions if and only if qf holds.
Setting infolevel to a nonzero value also provides information on how to interpret the above result.
infolevel[RegularChains] := 1: RealRootClassification(F, N, P, H, 3, 2, R); infolevel[RegularChains] := 0:
RealRootClassification: FINAL RESULT: RealRootClassification: The system has given number of real solution(s) IF AND ONLY IF RealRootClassification: [R[1] < 0 R[2] < 0 0 <= R[3] R[4] < 0] RealRootClassification: OR RealRootClassification: [0 < R[1] 0 < R[2] R[3] <= 0 R[4] < 0] RealRootClassification: where RealRootClassification: R[1] = c RealRootClassification: R[2] = a RealRootClassification: R[3] = b RealRootClassification: R[4] = 4*a*c-b^2 RealRootClassification: PROVIDED THAT RealRootClassification: c <> 0 RealRootClassification: a <> 0 RealRootClassification: 4*a*c-b^2 <> 0 RealRootClassification: 0.5e-2*seconds
regular_semi_algebraic_set,border_polynomial
There are two alternative ways to obtain the answer in a simpler (with less commands) but more coarse manner. The first one, shown above, is to set the infolevel to 1. The second one, shown below, is to use the Info command on the regular SAS. With this second approach, one can directly see the encoding of the regular SAS, that is, the parametric box; however, the conditions defining the regular SAS are not shown explicitly.
Info(ss, R);
c,a,b,4⁢a⁢c−b2,−1,−1,1,−1,1,1,−1,−1,,
More about border polynomials
The border polynomial is actually a list of polynomials such that the union of the hypersurfaces given by these polynomials contains all the "abnormal" (non-generic) parameter values of the parametric input SAS. For the previous example, the border polynomial is [c, a, 4 a c−b2]. It is intuitive that the zeroes of these polynomials represent degenerate cases: the first two indicate vanishing of the trailing and leading coefficients, respectively, and the last polynomial is the discriminant of the input polynomial. You can use the Info command to view the contents of the BP:
You might want to go further in analyzing the number of real solutions of the input SAS; that is, you might want to figure out what the answer is in these degenerate cases. This is very simple: it suffices to add the product of the polynomials in the BP to the list of equations when calling RealRootClassification (or to add the polynomials in the BP one by one to the equations of the system and call RealRootClassification accordingly).
In the example above, the question was for which parameter values does the input system has 2 distinct positive real solutions. When adding the polynomial 4 a c−b2 to the input system, below, you see that the list of regular SAS in the output from RealRootClassification is empty. This just means that it is impossible that the equation a x2+b x+c=0 has 2 distinct positive real solutions when its discriminant is zero.
rr := RealRootClassification([4*a*c-b^2, op(F)], N, P, H, 3, 2, R); bp := rr[2];Info(bp, R);
rr≔,border_polynomial
bp≔border_polynomial
b,a
The above output means: provided that b≠0≠c holds, the new system never admits two distinct positive real solutions.
More about regular semi-algebraic sets
A regular semi-algebraic set is essentially a subset of the real solutions of a regular chain. When this subset is finite, it can be encoded as a list of points with real coordinates. Each of these real coordinates must be an algebraic number defined by a regular chain and an isolating interval. Such an encoding is called a numerical box.
When this subset is not finite, the idea is to use a regular chain rc that is not zero-dimensional. Such a regular chain will have variables which are free in rc, that is, variables that do not belong to the main variables of the polynomials defining rc. Those free variables can be regarded as parameters. For rc to have real solutions, those free variables may need to satisfy some inequalities; this is where the quantifier-free formula qf comes in. More technically, qf defines an open semi-algebraic set (SAS) at every point of which rc specializes well and separates well (again, viewing the free variables of rc as parameters). This technical condition has the following important consequence: the number of real roots of rc is constant on the open SAS; moreover, each root of rc (complex or real) is a simple root on the open SAS. This in turn has the following consequence: the real solutions of rc can be indexed uniformly on the open SAS. Now this is where the list of lists of indices l comes in; it selects some of the real roots of rc.
To illustrate the concept of a regular semi-algebraic set in a sufficiently general situation, the original question will be modified as follows: Determine under which conditions on a,b,c,d the equation x2+d=0 has 2 distinct real solutions subject to d satisfying a d2+b d+c=0. Note that d plays a special role among the parameters, so it is ordered before a,b,c.
F:=x2+d,a⁢d2+b⁢d+c:N≔:P≔:H≔:R≔PolynomialRingx,d,a,b,c:rr≔RealRootClassificationF,N,P,H,4,2,R
Recall that the output consists of a list of regular SAS and a BP object. The command RepresentingBox applied to a regular SAS returns its encoding as either a numerical box or a parametric box; the command IsParametricBox will determine which of these two cases holds.
seqIsParametricBoxRepresentingBox⁡ss,R,ss=rr1
Display the BP using the Info command.
Inforr2,R
d
Select the first parametric box for further inspection. The command Info shows the raw data defining the parametric box, whereas the command Display pretty prints the conditions encoded by this data.
ss ≔ rr11:box≔RepresentingBoxss,R;Infobox,R;Displaybox, R;
d,−1,a⁢d2+b⁢d+c,1
c=−a⁢d2−b⁢dd<0
The three pieces of data defining a parametric box can also be accessed independently as shown below. Note that RepresentingChain applies directly to a regular SAS since both numerical boxes and parametric boxes have a representing regular chain. The components qf and l, however, are specific to parametric boxes.
(Note that objects of types regular_chain, regular_system, constructible_set, quantifier_free_formula, parametric_box, regular_semi_algebraic_set, and border_polynomial can all be printed by the Info and Display command.)
box≔RepresentingBoxss,R;rc≔RepresentingChainss,R;qf≔RepresentingQuantifierFreeFormulabox;l ≔ RepresentingRootIndexbox;Displayrc,R;Displayqf,R;Displaybox, R
qf≔quantifier_free_formula
l≔1
a⁢d2+b⁢d+c=0
d<0
An advanced example of real root classification
Define a polynomial ring.
unassign'p','q';R:=PolynomialRing⁡x,y,z,q,p:
Consider the following equations...
g1≔y2+z2−2⁢y⁢z⁢p−1:g2≔z2+x2−2⁢z⁢x⁢q−1:g3≔x2+y2−2⁢x⁢y⁢q−1:g4≔5 q2−1:F≔g1,g2,g3,g4:
...and constraints.
N:=:P≔x,y,z,1−p2,1−q2,p+1−2⁢q2:H:=:
The last 2 unknowns, p and q, are viewed as parameters. Suppose you want to know the conditions for the system to have no real solutions.
rr≔RealRootClassificationF,N,P,H,2,0,R
rr≔regular_semi_algebraic_set,regular_semi_algebraic_set,border_polynomial
Displayrr1, R;Displayrr2,R
q=RootOf⁡5⁢_Z2−1,index=real1p>0and2⁢p−1>0and5⁢p−3≠0and5⁢p+3>0and5⁢p2−1>0,q=RootOf⁡5⁢_Z2−1,index=real2p>0and2⁢p−1>0and5⁢p−3>0and5⁢p+3>0and5⁢p2−1>0
p,2⁢p−1,5⁢p−3,5⁢p+3,2⁢p+1,5⁢p2−1
The output should be read as follows: provided that not one of the polynomials in the BP (displayed in the last row) vanishes, the input system has no real solutions if and only if one of the following two conditions holds:
(1) p>0 ∧5 p+3>0 ∧ 2 p−1>0 ∧5 p2−1>0∧q is the first (from left to right) root of 5 q2−1;
(2) p >0 ∧5 p−3>0 ∧ 5 p+3>0 ∧2 p−1>0 ∧5 p2−1>0 ∧q is the second root of 5 q2−1.
Why do border polynomials form a type?
Consider again the parametric system in one variable and three parameters, associated with a generic univariate polynomial equation of degree 2.
R:=PolynomialRing⁡x,a,b,c:F≔a⁢x2+b⁢x+c:N≔:P≔:H≔:
The border polynomial is intrinsically associated with this system, independent of the prescribed number of real solutions of interest. The BP can be computed directly by the BorderPolynomial command.
bp:=BorderPolynomial⁡F,N,P,H,3,R:Infobp,R
a,−4⁢a⁢c+b2
The reason why border polynomials form a type in the RegularChains package (and cannot just be viewed as lists of polynomials) is that under special circumstances, the border polynomial of a parametric semi-algebraic system may degenerate.
The first such case is when the parameters do not appear in the system of polynomials; then the border polynomial is 1, as in the next example.
bp≔BorderPolynomialx2−1,,,,3,R:evalbp;Infobp,R
table⁡type=border_polynomial,PolynomialList=1,PolynomialRing=polynomial_ring
Another special circumstance is that of overdetermined or inconsistent systems; then the border polynomial is denoted as , as in the example below.
F:=a⁢x2+b⁢x+c,a,b:bp≔BorderPolynomialF,,,,1,R:evalbp;Infobp,R
table⁡type=border_polynomial,PolynomialList=,PolynomialRing=polynomial_ring
Finally, the last special case is when the input system has "generically" infinitely many complex solutions;
then the border polynomial is denoted as 0, as in the example below (this is because only two of the variables, b and c, are considered as parameters).
F:=a⁢x2+b⁢x+c:bp≔BorderPolynomialF,,,,2,R:evalbp;Infobp,R
table⁡type=border_polynomial,PolynomialList=0,PolynomialRing=polynomial_ring
0
6.4 Solving parametric semi-algebraic systems with application to the study stability of biological systems
The biological system is described by the following system of differential equations. Its right hand side encodes the equilibria:
ode := {diff(x(t),t) = -x(t)+s/(1+y(t)^2), diff(y(t),t)=-y(t)+s/(1+x(t)^2)}; F := [-x+s/(1+y^2), -y+s/(1+x^2)];
ode≔ⅆⅆtx⁡t=−x⁡t+s1+y⁡t2,ⅆⅆty⁡t=−y⁡t+s1+x⁡t2
F≔−x+sy2+1,−y+sx2+1
The following two Hurwitz determinants determine the stability of hyperbolic equilibria:
D1 := -(diff(F[1],x)+diff(F[2],y)); #D1 is 2 D2 := diff(F[1],x)*diff(F[2],y)-diff(F[1],y)*diff(F[2],x);
D1≔2
D2≔1−4⁢s2⁢y⁢xy2+12⁢x2+12
The semi-algebraic system below encodes the asymptotically stable hyperbolic equilibria:
P := [numer(normal(F[1]))=0, numer(normal(F[2]))=0, x>0, y>0, s>0, numer(D2)>0];
P≔−x⁢y2+s−x=0,−x2⁢y+s−y=0,0<x,0<y,0<s,0<x4⁢y4+2⁢x4⁢y2+2⁢x2⁢y4−4⁢s2⁢y⁢x+x4+4⁢x2⁢y2+y4+2⁢x2+2⁢y2+1
Compute a real comprehensive triangular decomposition of P w.r.t. the parameter s:
R := PolynomialRing([y, x, s]): ctd := RealComprehensiveTriangularize(P, 1, R);
ctd≔1,squarefree_semi_algebraic_system,2,squarefree_semi_algebraic_system,semi_algebraic_set,,semi_algebraic_set,1,semi_algebraic_set,2
Derive the values of s s.t. P has 2 positive real solutions, that is the biological system is bistable:
ctd2 := RealComprehensiveTriangularize(ctd, R, 2); Display(ctd2[2][1][1],R);
ctd2≔1,squarefree_semi_algebraic_system,semi_algebraic_set,1
2<s
The two asymptotically stable equilibria are represented by a squarefree_semi_algebraic_system.
ss := ctd2[1][1][2]; Display(ss, R);
ss≔squarefree_semi_algebraic_system
x⁢y−1=0x2−s⁢x+1=0y>0x>0s7⁢x−s6−6⁢x⁢s5+5⁢s4+8⁢x⁢s3−4⁢s2>0
7. FFT-based polynomial arithmetic
The module FastArithmeticTools supports the implementation of modular methods for computing with polynomials, algebraic extensions, and thus regular chains. This support consists of fundamental operations such as resultant, polynomial gcds, normal forms, etc.
The commands of this module work in prime characteristic and rely on asymptotically fast algorithms. Most of the underlying polynomial arithmetic is performed by C code and relies on (multi-dimensional) Fast Fourier Transform (FFT) and straight line programs (SLPs). This C code is highly optimized and implements the Truncated Fourier Transform (TFT) and an improved version of Montgomery's trick.
The commands IteratedResultantDim0 and IteratedResultantDim1 compute the iterated resultant of a polynomial with regards to a regular chain of dimension 0 and 1, respectively.
The commands NormalFormDim0 and ReduceCoefficientsDim0 compute the normal form of a polynomial with regards to a zero-dimensional regular chain.
The commands NormalizePolynomialDim0 and NormalizeRegularChainDim0 normalize a polynomial (with regards to a zero-dimensional regular chain) and a regular chain (with regards to itself).
The command RegularizeDim0 tests whether a polynomial is invertible modulo a zero-dimensional regular chain.
The commands RegularGcdBySpecializationCube, ResultantBySpecializationCube, and SubresultantChainSpecializationCube compute resultants and polynomial gcds modulo a regular chain using fast evaluation and interpolation.
The commands RandomRegularChainDim0 and RandomRegularChainDim1 compute random regular chains of given degrees.
Finally, the command BivariateModularTriangularize solves bivariate polynomial systems.
Most of the commands of FastArithmeticTools implements core operations on regular chains such as regularity test and polynomial gcd modulo a regular chain. However, these commands have several constraints. On top of the characteristic constraint (detailed below), the current regular chain must have dimension zero or one. There is only one exception: the command RegularGcdBySpecializationCube requires no assumption about the dimension. Note also that some commands do not take any regular chains as input (for instance, SubresultantChainSpecializationCube and ResultantBySpecializationCube).
Since FastArithmeticTools relies heavily on direct FFT and Montgomery's trick, the characteristic of the polynomial ring must be a prime number p satisfying the following properties. First, it should not be greater than 962592769. Secondly, the number p−1 should be divisible by a sufficiently large power of 2. The power 220 is often sufficient. If this power of 2 is not large enough, then an appropriate error message is returned. Using try-catch statements is highly recommended when programming with the commands of this submodule.
7.1 The impact of fast arithmetic
The purpose of the session below is to demonstrate how resultants can be computed with the module FastArithmeticTools.
restart; with(RegularChains); with(FastArithmeticTools);
Set the polynomial ring.
p := 962592769; vars := [a, b]; R := PolynomialRing(vars, p);
p≔962592769
vars≔a,b
Define the input polynomials.
degbound:=40;f1≔randpolyvars,dense,degree=degboundmodp:f2≔randpolyvars,dense,degree=degboundmodp:
degbound≔40
Evaluate/interpolate by subproduct tree techniques.
t1:=time⁡:SCube≔SubresultantChainSpecializationCubef1,f2,a,R,0;r1:=ResultantBySpecializationCube⁡f1,f2,a,SCube,R:t1≔time⁡−t1
SCube≔subresultant_chain_specialization_cube
t1≔0.263
Evaluate/interpolate by multi-dimensional TFT.
t2≔time:SCube:=SubresultantChainSpecializationCube⁡f1,f2,a,R,1;r2≔ResultantBySpecializationCubef1,f2,a,SCube,R:t2≔time−t2
t2≔0.166
Evaluate/interpolate without fast arithmetic.
t3≔time:r3≔Resultantf1,f2,amodp:t3≔time−t3
t3≔12.306
Compare the results.
evalb⁡`and`⁡r1=r2,r2=r3;degreer1; t1,t2,t3;
1600
0.263,0.166,12.306
7.2 The impact of modular methods together with fast arithmetic
The session below shows how polynomial gcds modulo regular chains can be computed with the module FastArithmeticTools. This applies also to polynomial gcds over towers of field extensions.
restart: with(RegularChains): with(FastArithmeticTools): with(ChainTools):
p := 962592769: vars := [a, b, c]: R := PolynomialRing(vars, p):
Define the polynomials.
degbound:=7;f1≔randpolyvars,dense,degree=degboundmodp:f2≔randpoly⁡vars,dense,degree=degboundmodp:
degbound≔7
t2:=time⁡:SCube≔SubresultantChainSpecializationCubef1,f2,a,R,1:r2:=ResultantBySpecializationCube⁡f[1],f[2],a,SCube,R:rc:=Chain⁡r2,Empty⁡R,R:g2:=RegularGcdBySpecializationCube⁡f[1],f[2],rc,SCube,R:t2:=time⁡−t2
t2≔0.237
Compute without fast arithmetic and without modular methods (evaluation / interpolation). Since the command RegularGcd tries to use modular methods whenever possible, change the characteristic of the ring to a small prime, so as to enforce the use of non-modular and non-FFT-based algorithms.
t3≔time:S≔PolynomialRingvars,257: r3≔Resultantf1,f2,amodp:rc≔Chainr3,Empty⁡S,S:g3≔RegularGcdf1,f2,a,rc,S:t≔time−t3
t≔12.734
7.3 Accelerating the core operations of the RegularChains library
Testing whether a polynomial is invertible modulo (the saturated ideal of) a zero-dimensional regular chain is a fundamental operation. Its implementation RegularizeDim0 in the FastArithmeticTools takes advantage of FFT-based polynomial arithmetic and improves on the command Regularize. Note that this latter command implements a more general algorithm (with no assumptions on characteristic or dimension).
p := 962592769: vars := [x1, x2, x3, x4]: R := PolynomialRing(vars, p):
Define a random (dense) regular chain and a polynomial.
N := nops(vars): d := 5; degrees := [3, 4, 5, 8]; rc := RandomRegularChainDim0(vars, degrees, p): p := `mod`(`mod`(randpoly(vars, dense, degree = d)+rand(), p), p):
d≔5
degrees≔3,4,5,8
Compute with the modular code.
t1:=time⁡:RegularizeDim0p,rc,R:t1:=time⁡−t1
t1≔0.183
Compute with the generic algorithm (without modular methods and without asymptotically fast arithmetic). Here again, change the characteristic to prevent use of the fast code.
t2≔time:Regularizep,rc,PolynomialRing⁡vars,17;t2≔time−t2
rc,
t2≔0.344
7.4 Solving large bivariate systems
In this example, solve a dense bivariate and square system which has 2500 solutions.
p := 469762049: vars := [x, y]: R := PolynomialRing(vars, p):
Define the polynomials and inspect their number of terms.
degbound:=50: f1≔randpolyvars,dense,degree=degboundmodp:f2≔randpolyvars,dense,degree=degboundmodp:nopsf1;nops⁡f2
1314
1321
Solve the system given by f1=f2=0 using fast arithmetic.
t:=time⁡:l≔BivariateModularTriangularizef1,f2,R:t≔time⁡−t
t≔0.691
Check the number of solutions and its number of terms.
map(NumberOfSolutions, l, R); map(nops, Equations(l[1], R));
2500
2404,2501
8. Cylindrical algebraic decomposition and quantifier elimination
The RegularChains library provides a set of commands for computing cylindrical algebraic decomposition (CAD, see command CylindricalAlgebraicDecompose) and doing quantifier elimination (QE, see command QuantifierElimination). The underlying algorithm first computes a cylindrical decomposition of the complex space (CCD, see command CylindricalDecompose), which is further refined into a cylindrical algebraic decomposition of the real space. Such an algorithm is different from the traditional projection-lifting algorithm introduced by George Collins and further refined by others.
with(ConstructibleSetTools):
8.1 Cylindrical decomposition of the complex space
A CCD is a partition of the complex space into disjoint cells such that they are cylindrically arranged,
meaning the projection of any two cells onto any lower dimensional space are either identical or disjoint,
and each cell is the zero set of a regular system.
R := PolynomialRing([y, x]); F := [x^2+y^2-1];
F≔x2+y2−1
ccd := CylindricalDecompose(F, R); Display(ccd, R);
ccd≔c_c_d
y=0x−1=0,x−1=0y≠0,y=0x+1=0,x+1=0y≠0,y2+x2−1=0x2−1≠0,y2+x2−1≠0x2−1≠0
ccd := CylindricalDecompose(F, R, output=system); Display(ccd, R);
ccd≔regular_system,regular_system,regular_system,regular_system,regular_system,regular_system
A CCD is best described by a complex cylindrical tree (CCT).
Informally, a CCT T of <[x_1,x_2,...,x_n] is a rooted tree with each non-root node described by a polynomial constraint p(x_1,...,x_i)=0, p(x_1,...,x_i)≠0, or "any x_i".
Moreover, the polynomial constraints in any path of T form a regular system such that the union of their zero sets form a CCD. The CCT can be displayed by the piecewise option.
R := PolynomialRing([y, x]); F := [x^2+y^2-1]; CylindricalDecompose(F, R, output=piecewise);
F≔y2+x2−1
1y=01otherwisex−1=01y=01otherwisex+1=01y2+x2−1=01otherwiseotherwise
If a set of polynomials, say F, is passed to CylindricalDecompose, then an F-invariant CCD
is computed. By F-invariant, we mean for any polynomial f of F and any cell C in the CCD,
either C is contained in the zero set of f or C has no intersection with the zero set of f.
One can use the command IsContained and Intersection to verify if the output satisfies the
invariance property.
R := PolynomialRing([y, x]); f:= x^2+y^2-1; g := x*y-1; F := [f,g]; lrs := CylindricalDecompose(F, R, output=system);
f≔y2+x2−1
g≔x⁢y−1
F≔y2+x2−1,x⁢y−1
lrs≔regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system,regular_system
For example, the first complex cell, namely the zero set of the first regular system, is contained
in the zero set of f.
rs1 := lrs[1]; Display(rs1, R); csf := Triangularize([f], [1], R, output=lazard); cs1 := ConstructibleSet([rs1], R); IsContained(cs1, csf, R);
rs1≔regular_system
y−1=0x=0
csf≔constructible_set
This cell has no intersection with the zero set of g.
rs1 := lrs[1]; Display(rs1, R); csg := Triangularize([g], [1], R, output=lazard); cs1 := ConstructibleSet([rs1], R); cs := Intersection(cs1, csg, R); IsEmpty(cs, R);
csg≔constructible_set
Besides a list of polynomials, a list of constraints (equations or inequations) are also allowed
to be the input of CylindricalDecompose. In this case, instead of a sign-invariant CCD, a (smaller) truth-invariant CCD will be computed.
R := PolynomialRing([y, x]); F := [f=0,g=0]; cad := CylindricalDecompose(F, R, output=piecewise);
F≔y2+x2−1=0,y⁢x−1=0
cad≔1y⁢x−1=01otherwisex4−x2+1=01otherwise
Several other output formats are supported, which are useful in some context. If the input is a list of constraints, the options ''output=cct" and "output=tree" generate a partial CCT expressing exactly their complex zeros while the options "output=ccd", "output=fulltree" and "output=piecewise" will generate a complete CCT. The options "output=tree" and "output=fulltree" represent the CCT in a nested list style;
R := PolynomialRing([y, x]); F := [f=0,g=0]; cad := CylindricalDecompose(F, R, output=cct); Display(cad, R); cad := CylindricalDecompose(F, R, output='ccd'); Display(cad, R); cad := CylindricalDecompose(F, R, output='piecewise'); cad := CylindricalDecompose(F, R, output='tree'); cad := CylindricalDecompose(F, R, output='fulltree');
cad≔c_c_t
x⁢y−1=0x4−x2+1=0x≠0
cad≔c_c_d
x⁢y−1=0x4−x2+1=0x≠0,x4−x2+1=0x⁢y−1≠0,x4−x2+1≠0
cad≔1,x4−x2+1=0,y⁢x−1=0
cad≔1,x4−x2+1,y⁢x−1,1,1,1
8.2 Cylindrical algebraic decomposition of the real space
The command CylindricalAlgebraicDecompose is used to compute a cylindrical algebraic decomposition of the real space. It supports different inputs, like list of polynomials, list of polynomial constraints, or list of list of polynomial constraints. It also provides different output formats, such as 'output'='piecewise', 'output'='tree', output='list', output='cadcell', output='rootof', output='cad'. The default output option is output='cad'.
If the input F is a list of polynomials, an F-invariant CAD, which means that any polynomial of F is sign-invariant on any cell of the output CAD, is computed.
restart; with(RegularChains): with(SemiAlgebraicSetTools): R := PolynomialRing([y, x]); F := [y^2-x, x-1]; cad := CylindricalAlgebraicDecompose(F, R);
F≔y2−x,x−1
cad≔c_a_d
By default, the output is a 'c_a_d' type. One can use Display or Info to show its cells.
y=yx<0,y<0x=0,y=0x=0,0<yx=0,y<−x0<x∧x<1,y=−x0<x∧x<1,−x<y∧y<x0<x∧x<1,y=x0<x∧x<1,x<y0<x∧x<1,y<−1x=1,y=−1x=1,−1<y∧y<1x=1,y=1x=1,1<yx=1,y<−x1<x,y=−x1<x,−x<y∧y<x1<x,y=x1<x,x<y1<x
Info(cad, R);
x<0,y=y,x=0,y<0,x=0,y=0,x=0,0<y,0<x∧x<1,y<−x,0<x∧x<1,y=−x,0<x∧x<1,−x<y∧y<x,0<x∧x<1,y=x,0<x∧x<1,x<y,x=1,y<−1,x=1,y=−1,x=1,−1<y∧y<1,x=1,y=1,x=1,1<y,1<x,y<−x,1<x,y=−x,1<x,−x<y∧y<x,1<x,y=x,1<x,x<y
The tree data structure of the CAD is best shown by the option 'output'='piecewise'.
R := PolynomialRing([y, x]); F := [y^2-x]; cad := CylindricalAlgebraicDecompose(F, R, output=piecewise);
F≔y2−x
cad≔1x<01y<01y=010<yx=01y<−x1y=−x1−x<y∧y<x1y=x1x<y0<x
The input can be a list of polynomial constraints, which incodes a conjunction formula or a semi-algebraic system. The Display command shows all the cells of the output CAD.
R := PolynomialRing([y, x]); F := [y^2-x=0, x-1=0]; cad := CylindricalAlgebraicDecompose(F, R); Display(cad, R);
F≔y2−x=0,x−1=0
y=yx<1,y<−1x=1,y=−1x=1,−1<y∧y<1x=1,y=1x=1,1<yx=1,y=y1<x
To see all the true cells, that is the cells satisfying the input constraints, 'output'='cadcell' can be used.
R := PolynomialRing([y, x]); cad := CylindricalAlgebraicDecompose([x^2+y^2-1=0, x*y-1/2=0], R, output=cadcell); Display(cad, R);
cad≔cad_cell,cad_cell
y=12⁢xx=−22,y=12⁢xx=22
As can be seen, the option 'output'='cadcell' does not attempt to make complete back substitution.
The option 'output'='rootof' instead supports complete back substitution and tries to merge adjacent cells to produce compact formula.
R := PolynomialRing([y, x]): cad := CylindricalAlgebraicDecompose([x^2+y^2-1=0, x*y-1/2=0], R, output=rootof);
cad≔x=−22,y=−22,x=22,y=22
R := PolynomialRing([y, x]): cad := CylindricalAlgebraicDecompose([x^2+y^2-1<=0], R, output=rootof);
cad≔−1≤x∧x≤1,−−x2+1≤y∧y≤−x2+1
The input can also be a list of list of polynomial constraints, which represents a formula in disjunctive normal form or a union of semi-algebraic systems.
R := PolynomialRing([y, x]); F := [[y^2-x=0], [x-1=0]]; cad := CylindricalAlgebraicDecompose(F, R, output=cadcell); Display(cad, R);
cad≔cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell
y=0x=0,y=−x0<x∧x<1,y=x0<x∧x<1,y<−1x=1,y=−1x=1,−1<y∧y<1x=1,y=1x=1,1<yx=1,y=−x1<x,y=x1<x
Note that only cells making the input formula satisfied are shown. To see all the cells, one
can use the default option 'output'='cad' or the option 'output'='allcell'.
R := PolynomialRing([y, x]); F := [[y^2-x=0], [x-1=0]]; cad := CylindricalAlgebraicDecompose(F, R, output=allcell); Display(cad, R);
cad≔cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell,cad_cell
Several other output formats are supported, including 'output'='tree', 'output'='list'.
R := PolynomialRing([y, x]); F := [y^2-x]; cad := CylindricalAlgebraicDecompose(F, R, output=list);
cad≔1,1,regular_chain,−12,−12,0,0,2,1,regular_chain,0,0,−12,−12,2,2,regular_chain,0,0,0,0,2,3,regular_chain,0,0,12,12,3,1,regular_chain,12,12,−32,−32,3,2,regular_chain,12,12,−14829112097152,−7414551048576,3,3,regular_chain,12,12,0,0,3,4,regular_chain,12,12,7414551048576,4634165536,3,5,regular_chain,12,12,32,32
R := PolynomialRing([y, x]); F := [y^2-x]; cad := CylindricalAlgebraicDecompose(F, R, output=tree);
cad≔1,−1,x,1,regular_chain,−12,−12,1,regular_chain,−12,−12,0,0,x,1,regular_chain,0,0,−1,y,1,regular_chain,0,0,−12,−12,y,1,regular_chain,0,0,0,0,1,y,1,regular_chain,0,0,12,12,1,x,1,regular_chain,12,12,−1,−y2+x,1,regular_chain,12,12,−32,−32,−y2+x,1,regular_chain,12,12,−14829112097152,−7414551048576,−y2+x,1,−y2+x,2,regular_chain,12,12,0,0,−y2+x,2,regular_chain,12,12,7414551048576,4634165536,1,−y2+x,2,regular_chain,12,12,32,32
The default algorithm of CylindricalAlgebraicDecompose is an incremental algorithm (CM) based on triangular decompositions proposed by Changbo Chen and Marc Moreno Maza on ASCM' 2012. An alternative algorithm (CMXY) proposed by Changbo Chen, Marc Moreno Maza, Bican Xia and Lu Yang on ISSAC' 2009, which is also the first generation of algorithm for computing CAD based on triangular decompositions, is available by the option 'method'='recursive'.
R := PolynomialRing([y, x]); F := [y^2-x]; cad := CylindricalAlgebraicDecompose(F, R, method=recursive, output=piecewise);
The CM algorithm can take advantage of equational constraints in a single semi-algebraic system.
That is, if the input is a list of polynomial constraints involving equations, by default, the option
'optimization'='EC' is enabled. To disable such optimization, one sets 'optimization'='false'.
R := PolynomialRing([y, x]); F := [x^2+y^2-1=0, y^2-x=0]; cad := CylindricalAlgebraicDecompose(F, R, optimization='EC', output=allcell): nops(cad); cad2 := CylindricalAlgebraicDecompose(F, R, optimization='false', output=allcell): nops(cad2);
F≔y2+x2−1=0,y2−x=0
9
53
If input is a list of list of polynomial constraints, by default an algorithm (RC-TTICAD) for computing truth-table invariant CAD is used to compute a smaller CAD. One could use the option 'optimization'='TTICAD' or 'optimization'='EC' to enable or disable it.
R := PolynomialRing([y, x]); F := [[(x-2)^2+(y-4)^2=0], [x^2+y^2-1=0, y^2-x=0]]; cad := CylindricalAlgebraicDecompose(F, R, optimization='TTICAD', output=allcell): nops(cad); cad2 := CylindricalAlgebraicDecompose(F, R, optimization='EC', output=allcell): nops(cad2);
F≔x−22+y−42=0,y2+x2−1=0,y2−x=0
33
65
To get a sample point of a CAD cell, the function SamplePoints can be called. Here no cost occurs since sample points are computed along the computation of the CAD and are stored in the type cad cell. A sample point is encoded by the type box, which is represented by a regular chain and an isolation cube. Such a representation allows one to easily test if the sign of a polynomial at the sample point by calling the function SignAtBox.
R := PolynomialRing([y, x]): cad := CylindricalAlgebraicDecompose([x^2+y^2-1=0, x*y-1/2=0],R,output=cadcell); Display(cad, R); sp := map(SamplePoints, cad, R); Display(sp, R); s := SignAtBox(x^2+y^2-2, sp[1], R);
sp≔box,box
y=−4634165536,−14829072097152x=−4634165536,−7414551048576,y=185363262144,7414571048576x=7414551048576,4634165536
s≔−1
8.3 Quantifier elimination
As one of the main applications of cylindrical algebraic decomposition, quantifier elimination is fully supported in the library. The function for doing quantifier elimination is QuantifierElimination.
The user interface of Quantifier Elimination relies on some features of the Logic library of Maple.
We introduce in addition the existential quantifier "&E" and the universal quantifier "&A".
Suppose we'd like to solve the following QE problem (due to Davenport and Heintz):
(∃ c) (∀ b, a) ((a = d ∧ b = c) ∨ ( a=c ∧ b = 1)) ⇒a^2 = b.
f := &E([c]), &A([b, a]), ((a=d) &and (b=c)) &or ((a=c) &and (b=1)) &implies (a^2=b);
f≔&E⁡c,&A⁡b,a,a=d&andb=c&ora=c&andb=1&impliesa2=b
out := QuantifierElimination(f);
out≔d−1=0&ord+1=0
Note that in the previous example, no variable order is specified.
In such case, the function will try to find the best elimination order according to some heuristic strategy.
R := PolynomialRing([x, a, b, c]); f := &E([x]), a*x^2+b*x+c=0; out := QuantifierElimination(f, R);
f≔&E⁡x,a⁢x2+b⁢x+c=0
out≔&or⁡c=0,&and⁡c<0,b<0,a=0,&and⁡c<0,b<0,0<a,&and⁡c<0,b<0,4⁢a⁢c−b2=0,&and⁡c<0,b<0,a<0,4⁢a⁢c−b2<0,&and⁡c<0,b=0,0<a,&and⁡c<0,0<b,a=0,&and⁡c<0,0<b,0<a,&and⁡c<0,0<b,4⁢a⁢c−b2=0,&and⁡c<0,0<b,a<0,4⁢a⁢c−b2<0,&and⁡0<c,b<0,a<0,&and⁡0<c,b<0,a=0,&and⁡0<c,b<0,4⁢a⁢c−b2=0,&and⁡0<c,b<0,0<a,4⁢a⁢c−b2<0,&and⁡0<c,b=0,a<0,&and⁡0<c,0<b,a<0,&and⁡0<c,0<b,a=0,&and⁡0<c,0<b,4⁢a⁢c−b2=0,&and⁡0<c,0<b,0<a,4⁢a⁢c−b2<0
By default, QuantifierElimination returns the standard quantifier free formula, namely Tarski formula.
Extended Tarski formula is supported by the option 'output'='rootof'.
f := &E([x]), a*x^2+b*x+c=0; out := QuantifierElimination(f,'output'='rootof');
f≔&E⁡x,x2⁢a+x⁢b+c=0
out≔&or⁡a<0&andb24⁢a≤c,a=0&andb≠0,&and⁡a=0,b=0,c=0,0<a&andc≤b24⁢a
More examples on generating extended Tarski Formula.
f := &E([y]), y^2+x^2=2; out := QuantifierElimination(f, output=rootof);
f≔&E⁡y,x2+y2=2
out≔−2≤x&andx≤2
f := &E([y]), y^4+x^4=2; out := QuantifierElimination(f, output=rootof);
f≔&E⁡y,x4+y4=2
out≔RootOf⁡_Z4−2,index=real1≤x&andx≤RootOf⁡_Z4−2,index=real2
evalf(op(1, out)); evalf(op(2, out));
−1.189207115≤x
x≤1.189207115
An application for computing control Lyapunov function.
f1 := -x_1+u: f2 := -x_1-x_2^3: V := a_1*x_1^2+a_2*x_2^2; Vt := diff(V, x_1)*f1 + diff(V, x_2)*f2;
V≔a_1⁢x_12+a_2⁢x_22
Vt≔2⁢a_1⁢x_1⁢−x_1+u+2⁢a_2⁢x_2⁢−x_23−x_1
QuantifierElimination( &A([x_1,x_2]), &E([u]), (x_1<>0) &or (x_2<>0) &implies ((V>0) &and (Vt<0)) );
0<a_2&and0<a_1
QuantifierElimination( &A([x_1, x_2]), &E([u]), (u=b_1*x_1+b_2*x_2) &and (a_1>0) &and (a_2>0) &and ((x_1<>0) &or (x_2<>0) &implies ((Vt<0))) );
&and⁡0<a_2,0<a_1,b_2⁢a_1−a_2=0,b_1<1
Simplification of the output.
Without simplification:
ff := &E([i,j]), (0 <= i) &and (i <= n) &and (0 <= j) &and (j <= n) &and (t = n - j) &and (p = i + j); R := PolynomialRing([i,j,p,t,n]); sols := QuantifierElimination(ff, R, output=rootof, simplification=false);
ff≔&E⁡i,j,0≤i&andi≤n&and0≤j&andj≤n&andt=n−j&andp=i+j
sols≔&or⁡&and⁡n=0,t=n,p=0,&and⁡0<n,t=0,p=n,&and⁡0<n,t=0,n<p,p<2⁢n,&and⁡0<n,t=0,p=2⁢n,&and⁡0<n,0<t,t<n,p=−t+n,&and⁡0<n,0<t,t<n,−t+n<p,p<−t+2⁢n,&and⁡0<n,0<t,t<n,p=−t+2⁢n,&and⁡0<n,t=n,p=0,&and⁡0<n,t=n,0<p,p<n,&and⁡0<n,t=n,p=n
With simplification:
sols := QuantifierElimination(ff, R, output=rootof, simplification=L4);
sols≔&and⁡0≤n,0≤t,t≤n,n−t≤p,p≤−t+2⁢n
9. Computing limits: from rational functions to topological closures
The AlgebraicGeometryTools submodule provides facilities for studying algebraic curves, surfaces and algebraic sets
of higher dimension. The commands currently available mainly focus on computing limits of "family of objects"
such as limits of family of secants in the case of tangent cone computation.
Different flavors of limit points
The command LimitPoints is part of AlgebraicGeometryTools package. The purpose of this command is to compute the limit points of a constructible set rc of dimension one. These limit points are corresponding to the values of the free variable of regular chain rc vanishing the product of the initials of the polynomials of rc.The command LimitPoints comes in two different types: 1) limit points w.r.t Zariski topology, 2) limit points w.r.t Euclidean topology. If one wants to compute the limit points of a constructible set with respect to Zariski topology, then one needs to use LimitPoints as follows:
restart:with(RegularChains): with(ChainTools): with(AlgebraicGeometryTools): R := PolynomialRing([x, y, z]): rc := Chain([y^5-z^4, x*z-y^2], Empty(R), R): lm := LimitPoints(rc, R): Display(lm, R);
x=0y=0z=0
Furthermore, the LimitPoints command uses an option called coefficient in order to indicate what the coefficient ring for the computations is. For the current implementation, coefficient can accept only complex and real corresponding to the limit points w.r.t Zariski and Euclidean topology, respectively. The option coefficient is set to complex by default. Therefore the following is equivalent to the computations above for lm.
rc := Chain([y^5-z^4, x*z-y^2], Empty(R), R): lm := LimitPoints(rc, R, coefficient = complex): Display(lm, R);
When the coefficient is set as complex, then the output of LimitPoints is called the complex limit points or for short only limit points of the regular chain rc. When the coefficient is set as real then this output is called the real limit points of the regular chain rc. The following shows how to compute the real limit points of the regular chain rc.
rc := Chain([y^5-z^4, x*z-y^2], Empty(R), R): lm := LimitPoints(rc, R, coefficient = real): Display(lm, R);
The command LimitPoints also has another option in order to indicate for which value of the free variable of regular chain rc one wants to compute the limit points of rc. In order to indicate this option, one new argument should be passed to LimitPoints which is a list of a single univariate polynomial in free variable of rc whose zeros are the corresponding values one wants to compute the limit points of rc at.
The following line shows how LimitPoints returns all the non-trivial limit points of rc.
rc:= Chain([y^5-z^4*(z+1)^5,x*z*(z+1)^2-y^2],Empty(R), R): lm := LimitPoints(rc, R); Display(lm, R);
lm≔regular_chain,regular_chain,regular_chain
x=0y=0z=0,x+1=0y=0z+1=0,x4−x3+x2−x+1=0y=0z+1=0
While the following computes the limit points only related to some values of the free variable of the regular chain rc.
lm := LimitPoints(rc, R, [z]):Display(lm, R);
Real limits vs complex limits
While for some cases real limit points might be equal to the complex limit points, this is not the case all the time. For the following example the real limit points and complex ones are all equal.
R := PolynomialRing([y, x, z]): rc := Chain([z^5+x^4-2*x^3+x^2, y*z^4+x^3-x^2], Empty(R), R): lm := LimitPoints(rc, R, coefficient = complex): Display(lm, R);
y=0x=0z=0
m := LimitPoints(rc, R, coefficient = real): Display(lm, R);
But the next example shows a case for which the real limit points are different from the complex ones, even if the complex limit points all have rational coefficients.
R := PolynomialRing([x, y, z]): rc:=Chain([y^(3)-2* y^(3)+y^(2)+z^(5), z^(4)* x+y^(3)-y^(2)], Empty(R),R): lm := LimitPoints(rc, R, coefficient = complex): Display(lm, R);
x=0y=0z=0,x=0y−1=0z=0
lm := LimitPoints(rc, R, coefficient = real): Display(lm, R);
x=0y−1=0z=0
Different output formats of LimitPoints
The command LimitPoints has two different output formats, which can be controlled by the output option. A user can indicate output option to be set as chain, which is the default of LimitPoints command, or rootof, each of which gives a different representation of the limit points of rc.
R := PolynomialRing([x, y, z]): rc := Chain([y^4-(z^2-2)^4, (z^2-2)*x-y^2], Empty(R), R): lm := LimitPoints(rc, R, [z^2-2], output = rootof, coefficient = real): Display(lm, R);
z=RootOf⁡_Z2−2,y=0,x=0
lm := LimitPoints(rc, R, [z^2-2], output = chain, coefficient = real): Display(lm, R);
x=0y=0z2−2=0
Computing the branches of the one-dimensional constructible sets
The command RegularChainBranches is part of AlgebraicGeometryTools package. The goal of this command is to compute a parametrization of the branches of a constructible set of dimension one represented by a regular chain. These parametrizations are actually the Puiseux parametrization of a constructible set when the free variable approaches zero. The following example show how to use this command without any extra option:
with(AlgebraicGeometryTools): R := PolynomialRing([x, y, z]): rc := Chain([-z^2+y, x*z-y^2], Empty(R), R): br := RegularChainBranches(rc, R, [z]);
br≔z=_T,y=_T2,x=_T3
rc := Chain([y^2*z+y+1, (z+2)*z*x^2+(y+1)*(x+1)], Empty(R), R): RegularChainBranches(rc, R, [z]); RegularChainBranches(rc, R, [z+2]);
z=_T0,y=−_T0−1,x=−1432⁢_T05+11432⁢_T04+5432⁢_T03−5216⁢_T02+112⁢_T0−12,z=_T0,y=−_T0−1,x=_T0−2⁢_T02+4⁢_T02−9⁢_T0−54432
z=_T1−2,y=1216⁢_T14+11216⁢_T13−5216⁢_T12−112⁢_T1−12,x=98⁢_T13+2⁢_T12+4⁢_T1−1,z=_T1−2,y=−1216⁢_T14−11216⁢_T13+427⁢_T12+13⁢_T1+1,x=38⁢_T13+12⁢_T12+_T1−1
Similar to the LimitPoints command, RegularChainBranches also works in two different modes: 1) complex, and 2) real. To switch between two different modes, user can use coefficient option which by default is set to be complex. The option coefficient indicates in which coefficient ring the corresponding parametrization of the branches will be computed. If it is set as real then it means that all the coefficients of the parametrizations are real numbers, complex, otherwise.
rc:=Chain([y^(3)-2* y^(3)+y^(2)+z^(5), z^(4)* x+y^(3)-y^(2)], Empty(R),R): br := RegularChainBranches(rc, R, [z], coefficient = complex);
br≔z=_T22,y=−_T25⁢_T25+2⁢RootOf⁡_Z2+12,x=_T22⁢_T220+6⁢_T215⁢RootOf⁡_Z2+1−10⁢_T210−88,z=_T22,y=−_T25⁢_T25−2⁢RootOf⁡_Z2+12,x=_T22⁢_T220−6⁢_T215⁢RootOf⁡_Z2+1−10⁢_T210−88,z=_T2,y=_T25+1,x=−_T211−2⁢_T26−_T2
br := RegularChainBranches(rc, R, [z], coefficient = real);
br≔z=_T3,y=_T35+1,x=−_T311−2⁢_T36−_T3
In the parametrization of the branches of the constructible set represented as a regular chain, a new (parametric) variable is introduced. This variable by default is chosen to be _T, possibly followed by a number, but also can be controlled by user. The following examples shows how this can be done:
rc := Chain([-z^2+y, x*z-y^2], Empty(R), R): br := RegularChainBranches(rc, R, [z^2+1], coefficient = complex);
br≔z=_T4+RootOf⁡_Z2+1,y=2⁢_T4⁢RootOf⁡_Z2+1+_T42−1,x=−_T48+3⁢_T46+3⁢_T42−1⁢RootOf⁡_Z2+1+3⁢_T47−_T45+_T43−3⁢_T4
rc := Chain([-z^2+y, x*z-y^2], Empty(R), R): br := RegularChainBranches(rc, R, [z^2+1], coefficient = complex, W);
br≔z=W+RootOf⁡_Z2+1,y=2⁢W⁢RootOf⁡_Z2+1+W2−1,x=−W8+3⁢W6+3⁢W2−1⁢RootOf⁡_Z2+1+3⁢W7−W5+W3−3⁢W
Also it is possible to determine how many terms can be computed in the parametrization of the branches of the regular chain rc. This feature can be used as follows:
First create a list of accuracies whose elements is equal to the number of polynomials in rc.
L:= [1,8];
L≔1,8
Then, we have:
R := PolynomialRing([x, y, z]): rc := Chain([y^2*z+y+1, (z+2)*z*x^2+(y+1)*(x+1)], Empty(R), R): RegularChainBranches(rc, R, [z],accuracies = L);
z=_T5,y=−_T5−1,x=_T5−2⁢_T54+2⁢_T53+4⁢_T52+8⁢_T5+16⁢143⁢_T58−396⁢_T57+1134⁢_T56−3402⁢_T55+10935⁢_T54−39366⁢_T53+177147⁢_T52−1594323⁢_T5−9565938⁢_T54−2⁢_T53+4⁢_T52−8⁢_T5+164897760256,z=_T5,y=−_T5−1,x=−_T5−2⁢_T54+2⁢_T53+4⁢_T52+8⁢_T5+16⁢143⁢_T58−396⁢_T57+1134⁢_T56−3402⁢_T55+10935⁢_T54−39366⁢_T53+177147⁢_T52−1594323⁢_T5−4782969⁢_T54−2⁢_T53+4⁢_T52−8⁢_T5+164897760256
If now we change the accuracies, we have the following:
L:= [1,4]: RegularChainBranches(rc, R, [z],accuracies = L);
z=_T6,y=−_T6−1,x=−5139968⁢_T69+734992⁢_T68−137139968⁢_T67+1003139968⁢_T66+181139968⁢_T65−18169984⁢_T64+293888⁢_T63−5216⁢_T62+112⁢_T6−12,z=_T6,y=−_T6−1,x=5139968⁢_T69−734992⁢_T68+137139968⁢_T67−1003139968⁢_T66−372187⁢_T65+742187⁢_T64−17243⁢_T63+427⁢_T62−13⁢_T6+1
It is worth mentioning that when the list L is not presented, it means a default value is computed for the list L. This value is called list of accuracies and it meets some requirements. These requirements can be found at Computing the Limit Points of the Quasi-component of a Regular Chain in Dimension One.
Computing limits of fractional multivariate polynomials (when origin is the singular point of denominator)
RationalFunctionLimit is a command of AlgebraicGeometryTools that is used to compute the limit of the fraction of multivariate polynomials at a point where this point is an isolated zero of the denominator. RationalFunctionLimit accepts two arguments: 1) the fraction of multivariate polynomials q, 2) a list of all the variables equal to some values, indicating the point we aim at computing the limit of q at. The following examples demonstrate how this command works:
restart: with(RegularChains): with(AlgebraicGeometryTools): RationalFunctionLimit(x^2*y*z^2/(x^4+y^4+z^4), [x = 0, y = 0, z = 0]);
RationalFunctionLimit((w*z+x^2+y^2)/(w^2+x^2+y^2+z^2), [x = 0, y = 0, z = 0, w = 0]);
undefined
RationalFunctionLimit(x^6/(w^6+l^2+t^2+x^2+y^2+z^2), [x = 0, y = 0, z = 0, w = 0, t = 0, l = 0]);
RationalFunctionLimit(x*y*z*w/(w^4+x^4+y^4+z^4), [x = 0, y = 0, z = 0, w = 0]);
RationalFunctionLimit((x*y+x*z-y*z)/(x^2+y^2+z^2), [x = 0, y = 0, z = 0]);
Computing tangent cone of algebraic curves
The command TangentCone is integrated into AlgebraicGeometryTools package. The goal of this command is to compute the tangent cone of a polynomial system of dimension one at some points on the curve. These points can do not necessarily have rational coefficients. The following shows how to use this command.
First introduce the polynomial ring:
Second, introduce the points using a zero-dimensional regular chain:
with(ChainTools):
rc := Chain([z-1, y, x], Empty(R), R):
Then, introduce the polynomial system of dimension one, and compute the tangent cone of this system at the point represented by rc:
Gs := [x^2+y^2+z^2-1, x^2-y^2-z*(z-1)]: tc := TangentCone(rc, Gs, R);
tc≔_z−1,3⁢_x2−_y2,regular_chain
There are two different representations for the output of TangentCone. Since the tangent cone of the polynomial systems of dimension one are lines, those lines can be represented both with their equations or slopes. The default is set as equations. Each format of the output can be used as follows:
tc := TangentCone(rc, Gs, R, output = equations);
tc := TangentCone(rc, Gs, R, output = slopes);
tc≔z,y−1,3⁢x2−1,regular_chain,z,y2−3,x−1,regular_chain
In order to indicate the equations or the slopes of the tangent cone, some new variables are used in order to distinguish the coordinate system of the equations and slopes from the original coordinate system. The default variables used for equation mode are the original names of variables where underscore is added as prefix to the variables. For slopes percentage added as prefix to original variables is used as default variables. However, the default for these variables can be controlled by user as follows:
tc := TangentCone(rc, Gs, R, [t, s, w], output = slopes);
tc≔w,s−1,3⁢t2−1,regular_chain,w,s2−3,t−1,regular_chain
Computing the tangent plane of the multivariate polynomials
TangentPlane is another command of AlgebraicGeometryTools package. Its goal is to compute the tangent plane of an algebraic surface represented by a polynomial at some point on the surface.
rc := Chain([z, y-1, x], Empty(R), R): tp := TangentPlane(rc, x*y, R);
tp≔_x,rc
Computing the intersection multiplicity of a polynomial system of dimension zero
The command TriangularizeWithMultiplicity is part of AlgebraicGeometryTools package. This command targets the intersection multiplicity computations of a polynomial system of dimension zero.
This command first attempts to solve this system using the Triangularize command of the RegularChains Library without taking multiplicity into consideration. Then for each point represented by the zero-dimensional regular chains in the triangular decomposition of the input system, it computes the intersection multiplicity of the original system at this related point.
R := PolynomialRing([z, y, x]): F := [x^2+y+z-1, y^2+x+z-1, z^2+x+y-1]: dec := TriangularizeWithMultiplicity(F, R): Display(dec, R);
1,z−x=0y−x=0x2+2⁢x−1=0,2,z=0y=0x−1=0,2,z=0y−1=0x=0,2,z−1=0y=0x=0
Return to Index for Example Worksheets
Download Help Document