int Cauchy_First_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound);with:
int Cauchy_First_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound);This procedure returns an interval such that for any polynomial in the set and for any root of this polynomial . A failure code of 0 is returned if Coeff(1) or Coeff(Degree+1) contains 0 or if Degree=0. On success the returned code is 1.
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; Num=Cauchy_First_Bound_Interval(3,Coeff,Bound); Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=Cauchy_First_Bound_Interval(3,Coeff_App,Bound);In the first case the procedure find that the absolute value of the roots lie in [0.6,4] while in the second case the range is [0.58,4.44444].
int Cauchy_Second_Bound_Interval(int Degree,VECTOR &Coeff,double *Bound);with:
int Cauchy_Second_Bound_Inverse_Interval(int Degree,VECTOR &Coeff,double *Bound);This procedure fail and returns 0 if Degree=0, Degree=1 and Coeff(2)=0 or Coeff(1)=0. There is also an implementation for interval polynomial:
int Cauchy_Second_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL Bound);This procedure will return a failure code of 0 if Degree=0, Degree=1 and Coeff(2) contain 0, or if Coeff(Degree+1) contains 0. In that case if Bound=[a,b], then for all polynomials in the set the positive roots are all lower than b while for some polynomial in the set the roots are lower than a. Equivalently we have:
int Cauchy_Second_Bound_Inverse_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL Bound);In that case if Bound=[a,b], then for all polynomials in the set the positive roots are all lower than a while for some polynomial in the set the roots are lower than b.
A global procedure enable to get at the same time the upper and lower bound of the positive roots:
int Cauchy_Second_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound); int Cauchy_Second_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Lower,INTERVAL &Upper);In the latter case the interval lower bound is in Lower and the interval upper bound in Upper. It is also possible to determine the lower bound of the negative roots using the procedures:
int Cauchy_Second_Bound_Negative_Interval(int Degree,VECTOR &Coeff,double *Bound); int Cauchy_Second_Bound_Negative_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound);while the upper bound of the negative roots can be determined using:
int Cauchy_Second_Bound_Negative_Inverse_Interval(int Degree,VECTOR &Coeff,double *Bound); int Cauchy_Second_Bound_Negative_Inverse_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Bound);Both the upper and lower bound of the negative roots can be found using:
int Cauchy_Second_Bound_Negative_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound); int Cauchy_Second_Bound_Negative_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Lower,INTERVAL &Upper);
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; Num=Cauchy_Second_Bound_Interval(3,Coeff,&bound); Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=Cauchy_Second_Bound_Interval(3,Coeff_App,Bound);In the first case we find that all the roots are lower than 2 and in the second that the roots have bounds [2.44444,2.44444]. If we have used the lower bound procedures we will have found that all the roots are positive.
int Cauchy_Third_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound)Coeff[1] cannot be 0. The procedure:
int Cauchy_All_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Bound)will return the result of a successive application of the first and third Cauchy bounds.
The upper bound of the value of the positive real root is:
If we define:
int MacLaurin_Bound_Interval(int Degree,VECTOR &Coeff,double *Bound);with:
On success the return code is 1. There is also a procedure for the interval polynomial:
int MacLaurin_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL Bound);This procedure fail and returns 0 if Degree=0, Degree=1 and Coeff(2) and if Coeff(Degree+1). In that case if Bound=[a,b], then for all polynomials in the set the roots are all lower than b while for some polynomial in the set the roots are lower than a.
It is also possible to determine the lower bound of the positive roots using the procedures:
int MacLaurin_Bound_Inverse_Interval(int Degree,VECTOR &Coeff,double *Bound); int MacLaurin_Bound_Inverse_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound);In the later case if Bound=[a,b], then for all polynomials in the set the roots are all lower than a while for some polynomial in the set the roots are lower than b. To get directly both lower and upper bound of the positive roots you may use:
int MacLaurin_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound) int MacLaurin_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Lower, INTERVAL &Upper)In the latter case the interval lower bound is in Lower and the interval upper bound in Upper.
It is also possible to determine the lower bound of the negative roots using the procedures:
int MacLaurin_Bound_Negative_Interval(int Degree,VECTOR &Coeff,double *Bound); int MacLaurin_Bound_Negative_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound);Similarly it is possible to determine the upper bound of the negative roots using the procedures:
int MacLaurin_Bound_Negative_Inverse_Interval(int Degree,VECTOR &Coeff,double *Bound); int MacLaurin_Bound_Negative_Inverse_Interval(int Degree, INTERVAL_VECTOR &Coeff,INTERVAL &Bound);To get directly both lower and upper bound of the negative roots you may use:
int MacLaurin_Bound_Negative_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound) int MacLaurin_Bound_Negative_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Lower, INTERVAL &Upper)
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; Num=MacLaurin_Bound_Interval(3,Coeff,&bound); Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=MacLaurin_Bound_Interval(3,Coeff_App,Bound);In the first case we find that all the roots are lower than 4 and in the second that the roots have bounds [4.44444,4.44444]. If we have used the lower bound procedures we will have found that all the roots are greater than -1.
int Laguerre_Bound_Interval(int Degree,VECTOR &Coeff,double sens,int MaxIter,double *bound);with:
The lower bound of the root may be determined by:
int Laguerre_Bound_Inverse_Interval(int Degree,VECTOR &Coeff1,double amp_sens, int MaxIter,double *bound);We have also a procedure which determine upper and lower bound for the real roots:
int Laguerre_Bound_Interval(int Degree,VECTOR &Coeff,double sens,int MaxIter,INTERVAL &Bound);All the real roots lie within Bound. We may also use this procedure for interval polynomial:
int Laguerre_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,double sens, int MaxIter,INTERVAL &Bound);This procedure fail and returns 0 if Degree=0, Coeff(1), if Coeff(Degree+1) and if the number of iteration exceed MaxIter. If Bound=[a,b], then the real roots of all the polynomial in the set are lower than b and for some polynomial in the set the roots may be lower than a. A similar procedure exists for upper and lower bound.
int Laguerre_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,double sens, int MaxIter,INTERVAL &Lower,INTERVAL &Upper);In that case Upper=[a,b] will be such that value of all roots of any polynomial within the set is lower than b, while for some polynomial they will be lower than a. On the other hand Lower=[a,b] will be such that the value of all roots of any polynomial within the set is greater than a, while for some polynomial they will be greater than b.
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; Num=Laguerre_Bound_Interval(3,Coeff,0.1,50,Bound); Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=Laguerre_Bound_Interval(3,Coeff_App,0.1,50,Lower,Upper);leads to Bound=[1.15385,1.3], Lower=[1.08209,1.40271], Upper=[1.21818,1.52222].
int Laguerre_Second_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound);with:
int Laguerre_Second_Bound_Interval(int Degree, INTERVAL_VECTOR &Coeff,INTERVAL &Lower,INTERVAL &Upper);In that case Upper=[a,b] will be such that the maximal value of all roots of any polynomial within the set is lower than b, while for some polynomial they will be lower than a. On the other hand Lower=[a,b] will be such that the minimal value of all roots of any polynomial within the set is greater than a, while for some polynomial they will be greater than b.
In the implementation we define as the smallest real which satisfy . If we find such that , then we increase by a given positive value sens and start again. We limit the number of iteration of the scheme by giving a maximal value for the number of iteration:
int Newton_Bound_Interval(int Degree,VECTOR &Coeff1,double amp_sens,int MaxIter,double *bound);with:
int Newton_Bound_Inverse_Interval(int Degree,VECTOR &Coeff1,double amp_sens, int MaxIter,double *bound);We have also a procedure which determine upper and lower bound for the real roots:
int Newton_Bound_Interval(int Degree,VECTOR &Coeff1,double amp_sens, int MaxIter,INTERVAL &Bound);All the real roots lie within Bound. We may also use this procedure for interval polynomial:
int Newton_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,double sens, int MaxIter,INTERVAL &Bound);This procedure fail and returns 0 if Degree=0, Coeff(1), if Coeff(Degree+1) and if the number of iteration exceed MaxIter. If Bound=[a,b], then the real roots of all the polynomial in the set are lower than b and for some polynomial in the set the roots may be lower than a. A similar procedure exists for upper and lower bound.
int Newton_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,double sens, int MaxIter,INTERVAL &Lower,INTERVAL &Upper);In that case Upper=[a,b] will be such that value of all roots of any polynomial within the set is lower than b, while for some polynomial they will be lower than a. On the other hand Lower=[a,b] will be such that the value of all roots of any polynomial within the set is greater than a, while for some polynomial they will be greater than b.
int Newton_Second_Bound_Interval(int Degree,VECTOR &Coeff,double *bound);with:
int Newton_Second_Bound_Inverse_Interval(int Degree,VECTOR &Coeff,double *bound);An upper and lower bound on the absolute value of the roots may be compute by:
int Newton_Second_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound);In that case if Bound=[a,b] we have for all root : a b.
Similar procedures exist for interval polynomial:
int Newton_Second_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound); int Newton_Second_Bound_Inverse_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Bound); int Newton_Second_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &L, INTERVAL &U);where
int Joyal_Bound_Interval(int Degre,INTERVAL_VECTOR &Coeff,INTERVAL &Bound)returns in Bound an upper bound of the modulus of the roots of the polynomial of degree Degre and interval coefficients Coeff. The procedure returns 0 if is not equal to 1, 1 otherwise.
Now assume that we have calculated the coefficients of the polynomial where are known quantities. If we determine a polynomial that has 2 positive roots in the range , then has roots in the disk . Hence the absolute value of the real part of the roots is bounded by . As we get that the real part of the root satisfies . As this shows that has roots whose real part is greater than .
int Pellet(int Degre,INTERVAL_VECTOR &Coeff,double R)where Degre is the degree of the polynomial, Coeff are the coefficients of the polynomial . This procedure returns 1 if roots whose real part is greater than .
int Global_Positive_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound); int Global_Negative_Bound_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound);with:
int Global_Positive_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Lower,INTERVAL &Upper); int Global_Negative_Bound_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL &Lower,INTERVAL &Upper);where Lower is an interval on the lower bound: for positive roots and if Lower=[a,b] then the roots of any polynomial in the set is greater than a while some polynomial have root greater than b. Conversely if Upper=[a,b] the roots of any polynomial in the set is lower than b while some polynomial have root lower than a.
Both procedures for real roots have been regrouped in
void ALIAS_Find_Bound_Polynom(int Degree, INTERVAL_VECTOR (* TheCoeff)(INTERVAL_VECTOR &), INTERVAL_VECTOR &PALL,INTERVAL &Space, INTERVAL &Bound)where
Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=Global_Positive_Bound_Interval(3,Coeff_App,Lower,Upper);which leads to Lower=[1.1487,1.42957], Upper=[1.15224,1.43049].
The above procedure may give some sharp bounds. For example consider the Wilkinson polynomial of order 22 (which has as roots 1,2,,21,22) we get 0 negative roots while the positive roots are bounded by [0.790447,22.1087].
The test program Test_Bound_UP enable to test the bound procedures for any polynomial. This program take as first argument the name of a file giving the coefficients of the polynomial by increasing power of the variable. The program will print the bounds determined by all the previous procedures and then the bounds determined using the global implementation. Then the same treatment will be applied on the interval polynomial whose coefficients are intervals centered at the coefficients find in the file with a width of 0.2
int Kantorovitch(int Degree,VECTOR &Coeff,REAL Input,double *eps)with
int Kantorovitch(int Degree,INTERVAL_VECTOR &Coeff,REAL Input,double *eps)If this procedure returns 1, then any polynomial in the set of interval polynomial has an unique solution in the interval [Input-eps,Input+eps]. There is also an implementation which take into account rounding errors:
int Kantorovitch_Fast_Safe(int Degree,INTERVAL_VECTOR &Coeff,REAL Input,double *eps)in which "safe" interval value of the coefficients have been pre-computed.
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; Num=Kantorovitch(3,Coeff,1.2,&eps); Coeff_App(1)= INTERVAL(-3.1,-2.9);Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9);Coeff_App(4)=INTERVAL(0.9,1.1); Num=Kantorovitch(3,Coeff_App,1.2,&eps);In the first case Kantorovitch returns 1 and has determined that there is an unique solution in the interval [1.04082,1.35918]. Using Newton method we find the root 1.27568220371567 with residue 2.80147904874184e-10. For the interval polynomial Kantorovitch returns also 1 and find an unique solution in [1.05718,1.34282].
VECTOR SumN_Polynomial_Interval(int Degree,VECTOR &Coeff)with:
INTERVAL_VECTOR SumN_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff)which returns intervals including the . This procedure returns 0 if 0 is included in the leading interval.
VECTOR ProdN_Polynomial_Interval(int Degree,VECTOR &Coeff)with:
INTERVAL_VECTOR ProdN_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff)which returns intervals including the . This procedure returns 0 if 0 is included in the leading interval.
INT Descartes_Lemma_Interval(int Degree,VECTOR &Coeff)with:
There is an implementation of this method for interval polynomial. Here it is necessary to introduce an additional parameter to indicate the confidence we have in the result. The procedure is implemented as:
INT Descartes_Lemma_Interval(int Degree,INTERVAL_VECTOR &Coeff,int *Confidence);Confidence is a quality index:
INT Descartes_Lemma_Negative_Interval(int Degree,VECTOR &Coeff) INT Descartes_Lemma_Negative_Interval(int Degree,INTERVAL_VECTOR &Coeff,int *Confidence)
INT Budan_Fourier_Interval(int Degree,VECTOR &Coeff,INTERVAL In) INT Budan_Fourier_Interval(int Degree,INTEGER_VECTOR &Coeff,INTERVAL In)with:
INT Budan_Fourier_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL In,int *Confidence)where Confidence is a quality index for the result:
INT Budan_Fourier_Safe_Interval(int Degree,VECTOR &Coeff, INTERVAL In,INTERVAL &NbRoot);The procedure returns 1 in case of success and an interval for the number of roots. If NbRoot=[a,b], then if a =b the number of roots is either a,a-2, and if a b the number of roots is lower than b. If "safe" value of the coefficients have been pre-computed you may use:
INT Budan_Fourier_Fast_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff, INTERVAL In,INTERVAL &NbRoot);Another safe procedure is:
INT Budan_Fourier_Interval(int Degree,INTEGER_VECTOR &Coeff,int Inf,int Sup)where the coefficients and the bounds are integers.
Coeff(1)= -3;Coeff(2)=2;Coeff(3)=-1;Coeff(4)=1; P=INTERVAL(0.0,2.0); Num= Budan_Fourier_Interval(3,Coeff,P);Num is 3 meaning that has either 3 or 1 roots in the interval. Now assume that we have an interval polynomial:
Coeff_App(1)= INTERVAL(-3.1,-2.9); Coeff_App(2)=INTERVAL(1.9,2.1); Coeff_App(3)=INTERVAL(-1.1,-0.9); Coeff_App(4)=INTERVAL(0.9,1.1); Num= Budan_Fourier_Interval(Degree,Coeff_App,P,&Confidence);Num is also 3 with Confidence=1 meaning that the number of roots for any polynomial is either 3 or 1.
The drawback of Sturm method is that the absolute value of the coefficients increase quickly when computing the sequence. Numerical rounding errors may then affect the result. The alternate method of Budan-Fourier (see section 5.5.2) is less sensitive to rounding errors although it provides less information than Sturm method.
This procedure determines the number of real roots of an univariate polynomial in a given interval. It is implemented as:
int Sturm_Interval(int Degree,VECTOR &Coeff,INTERVAL &In); int Sturm_Interval(int Degree,INTEGER_VECTOR &Coeff,INTERVAL &In);
int Sturm_Safe_Interval(int Degree,VECTOR &Coeff,INTERVAL &In,INTERVAL &NbRoot);which returns 1 in case of success and an interval NbRoot which contain the number of roots. If NbRoot=[a,b], then if a =b the number of roots is a and if a b the number of roots is lower than b. Another safe procedure can be used if the coefficients are integers and the interval is also defined by integer numbers:
int Sturm_Interval(int Degree,INTEGER_VECTOR &Coeff,int Inf,int Sup);This procedure will return -1 if all the coefficients are 0 and -2 if at some point of the process an integer larger than the largest machine integer is encountered (Not yet implemented).
The test program Test_Nb_Root_Up enable to test Budan-Fourier and Sturm method on any polynomial whose coefficients are defined in a file, by increasing degree of the power of the unknown.
int Huat_Polynomial_Interval(int Degree,VECTOR &Coeff);with:
int Huat_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff);This procedure will return 1 if all the polynomials in the set have their roots real, -1 if some polynomials in the set have all roots real but some others have complex roots and 0 if all the polynomials in the set have complex roots.
int Min_Sep_Root_Interval(int Degree,VECTOR &Coeff,double &min);with
int Max_Sep_Root_Interval(int Degree,VECTOR &Coeff,double &max);while upper and lower bounds may be determined with:
int Bound_Sep_Root_Interval(int Degree,VECTOR &Coeff,INTERVAL &Bound);There is also a procedure to determine a lower bound for interval polynomial:
int Min_Sep_Root_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL &Lower);If Lower=[a,b] then some polynomials in the set will have a minimal distance between the roots greater than b while all the polynomials in the set have a minimal distance greater than a.
int ALIAS_Min_Max_Is_Root(int Degree, int NbParameter, int HasInterval, INTERVAL_VECTOR (* TheCoeff)(INTERVAL_VECTOR &), int Iteration, INTERVAL_VECTOR &Par, double *Root, int Type, int (* Solve_Poly)(double *, int *,double *))may be used to rest if a polynomial in a set may have as real root one of two pre-defined value.
For some applications it may be interesting to determine if a polynomial in a set defined by a parametric polynomial has the real part of one of its roots equal to a pre-defined value. This may be done by using the procedure
int ALIAS_Is_Root_RealPart(int Degree, int NbParameter, int HasInterval, INTERVAL_VECTOR (* TheCoeff)(INTERVAL_VECTOR &), INTERVAL_VECTOR (* TheCoeffCentered)(INTERVAL_VECTOR&,double a), int Iteration, INTERVAL_VECTOR &Par, double *Root, INTERVAL_VECTOR (* EvaluateComplex)(int,int,INTERVAL_VECTOR &), int (* Simp)(INTERVAL_VECTOR &))where
The following procedures enable to add polynomials with real,interval or integer coefficients:
VECTOR Add_Polynomial_Interval(int n1,VECTOR &Coeff1,int n2,VECTOR &Coeff2); INTERVAL_VECTOR Add_Polynomial_Interval(int n1,INTERVAL_VECTOR &Coeff1, int n2,INTERVAL_VECTOR &Coeff2); INTEGER_VECTOR Add_Polynomial_Interval(int n1,INTEGER_VECTOR &Coeff1, int n2,INTEGER_VECTOR &Coeff2);with:
INTERVAL_VECTOR Add_Polynomial_Safe_Interval(int n1,VECTOR &Coeff1,int n2,VECTOR &Coeff2);
The following procedures returns the degree of the product of two polynomial either with real or integer coefficients:
int Degree_Product_Polynomial_Interval(int n1,VECTOR &Coeff1,int n2,VECTOR &Coeff2); int Degree_Product_Polynomial_Interval(int n1,INTEGER_VECTOR &Coeff1,int n2, INTEGER_VECTOR &Coeff2);Then you may use the following procedure to compute the product of polynomial either with real,integer or interval coefficients:
VECTOR Multiply_Polynomial_Interval(int n1,VECTOR &Coeff1,int n2,VECTOR &Coeff2); INTEGER_VECTOR Multiply_Polynomial_Interval(int n1,INTEGER_VECTOR &Coeff1, int n2,INTEGER_VECTOR &Coeff2); INTERVAL_VECTOR Multiply_Polynomial_Interval(int n1,INTERVAL_VECTOR &Coeff1, int n2,INTERVAL_VECTOR &Coeff2);All these procedures return the coefficients of the product, the leading term being 0 only if one polynomial is equal to 0.
To take into account the rounding errors you may use:
INTERVAL_VECTOR Multiply_Polynomial_Safe_Interval(int n1,VECTOR &Coeff1,int n2,VECTOR &Coeff2);
The evaluation of a polynomial for a given value is implemented as:
REAL Evaluate_Polynomial_Interval(int Degree,VECTOR &Coeff,REAL P) INTERVAL Evaluate_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff,REAL P) INTERVAL Evaluate_Polynomial_Interval(int Degree,VECTOR &Coeff,INTERVAL P) INTERVAL Evaluate_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL P) REAL Evaluate_Polynomial_Interval(int Degree,INTEGER_VECTOR &Coeff,REAL P); int Evaluate_Polynomial_Interval(int Degree,INTEGER_VECTOR &Coeff,INT P);with:
[11977379510.705810546875,11977410100.791748046875]A better evaluation may be obtained if we use a centered form of the polynomial. Consider the polynomials:
VECTOR Coeff_Polynomial_Centered_Interval(int Degree,VECTOR &Coeff,REAL P); INTERVAL_VECTOR Coeff_Polynomial_Centered_Interval(int Degree, INTERVAL_VECTOR &Coeff,REAL P);enable to compute the for the centered form at P either for polynomial or interval polynomial. To take into account numerical errors you may use:
INTERVAL_VECTOR Coeff_Polynomial_Centered_Safe_Interval(int Degree,VECTOR &Coeff,REAL P); INTERVAL_VECTOR Coeff_Polynomial_Centered_Fast_Safe_Interval(int Degree, INTERVAL_VECTOR &Coeff,REAL P);which return safe value for the coefficients (in the second form we assume that you have pre-computed safe value for the coefficients of the polynomial using the procedure described in section 5.9.10).
Then we may use the procedures:
REAL Evaluate_Polynomial_Centered_Interval(int Degree,VECTOR &Coeff,REAL Center,REAL P); INTERVAL Evaluate_Polynomial_Centered_Interval(int Degree,VECTOR &Coeff,INTERVAL P); INTERVAL Evaluate_Polynomial_Centered_Interval(int Degree,INTERVAL_VECTOR &Coeff, REAL Center,REAL P); INTERVAL Evaluate_Polynomial_Centered_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL P);These procedures return the evaluation of the polynomial at P using the centered form at Center or at the middle point of P if is an interval. For example for the Wilkinson polynomial at order 15 the evaluation for 15.1 using the centered form at 15 leads to 11977396665.00650787353516 which is largely better than the previous evaluation.
INTERVAL Evaluate_Polynomial_Safe_Interval(int Degree,VECTOR &Coeff,REAL P); INTERVAL Evaluate_Polynomial_Safe_Interval(int Degree,VECTOR &Coeff,INTERVAL P); INTERVAL Evaluate_Polynomial_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff,REAL P); INTERVAL Evaluate_Polynomial_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL P);
For example for the Wilkinson polynomial at order 15 the
evaluation for 15.1 leads to the interval:
INTERVAL Evaluate_Polynomial_Fast_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff,REAL P); INTERVAL Evaluate_Polynomial_Fast_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL P);which are faster. If you want to use a centered form you may use:
INTERVAL Evaluate_Polynomial_Centered_Safe_Interval(int Degree,VECTOR &Coeff,REAL P); INTERVAL Evaluate_Polynomial_Centered_Safe_Interval(int Degree,VECTOR &Coeff,INTERVAL P); INTERVAL Evaluate_Polynomial_Centered_Fast_Safe_Interval(int Degree, INTERVAL_VECTOR &Coeff,REAL P); INTERVAL Evaluate_Polynomial_Centered_Fast_Safe_Interval(int Degree, INTERVAL_VECTOR &Coeff,INTERVAL P);in which the two last forms assume that you have pre-computed a safe value of the coefficients of the polynomial.
The evaluation of a polynomial with real coefficients at a complex point may be performed with:
INTERVAL_VECTOR Evaluate_Complex_Poly(int deg, INTERVAL_VECTOR &Coeff, INTERVAL &XR,INTERVAL &XI)where XR is the real part of the point and XI its imaginary part. This procedure returns an interval vector whose first element is the real part of the evaluation and the second element its imaginary part.
int Sign_Polynomial_Interval(int Degree,VECTOR &Coeff,REAL P) int Sign_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff,REAL P) int Sign_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff,REAL P) int Sign_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff,INTERVAL P)with:
This procedure returns 1 if the polynomial is positive, -1 if it is negative, 0 if it is 0 and 2 if the sign is either affected by numerical errors (if Coeff and P are REAL) or is not constant (if Coeff or P are INTERVAL_VECTOR).
VECTOR Derivative_Polynomial_Interval(int Degree,VECTOR &Coeff) INTEGER_VECTOR Derivative_Polynomial_Interval(int Degree,INTEGER_VECTOR &Coeff); VECTOR Nth_Derivative_Polynomial_Interval(int Degree,VECTOR &Coeff,int n)These procedures enable to get the coefficients of the first and n-th derivative of a polynomial defined by its REAL or INT coefficients.
Due to rounding errors there may be errors in the coefficients provided by the previous procedures. The procedure:
INTERVAL_VECTOR Derivative_Polynomial_Safe_Interval(int Degree,VECTOR &Coeff);will return an INTERVAL_VECTOR (i.e. a set of intervals) which are guaranteed to include the true value of the coefficients of the derivative. A faster procedure may be used if "safe" interval values of the coefficients have been pre-computed:
INTERVAL_VECTOR Derivative_Polynomial_Fast_Safe_Interval(int Degree,INTERVAL_VECTOR &Coeff);
If we deal with polynomial with interval coefficients the following procedures may be used:
INTERVAL_VECTOR Derivative_Polynomial_Interval(int Degree,INTERVAL_VECTOR &Coeff) INTERVAL_VECTOR Nth_Derivative_Polynomial_Interval(int Degree, INTERVAL_VECTOR &Coeff,int n)
The procedure:
void ALIAS_Euclidian_Division(int Degree,INTERVAL_VECTOR &Coeff1, INTERVAL_VECTOR &Coeff2,INTERVAL &Residu,INTERVAL &a)computes the division of the polynomial P with interval coefficients Coeff1 by x-a and returns the polynomial P1 with coefficients Coeff2 such that P=(x-a)P1+Residu
Another procedure that perform the same process if a is a double is
void Divide_Single(int Degree,INTERVAL_VECTOR &Coeff1,double a, INTERVAL_VECTOR &Coeff2, INTERVAL &Residu)For dividing a polynomial by the product of polynomials of type so that
INTERVAL Divide_Evaluate_Multiple(int Degree,INTERVAL_VECTOR &Coeff1, int n,double *a,INTERVAL_VECTOR &X)where
For the Euclidian division by an arbitrary polynomial you may use
int Divide_Polynom(int Degree,INTERVAL_VECTOR &Coeff,int DegreeDivisor, INTERVAL_VECTOR &CoeffDivisor, INTERVAL_VECTOR &CoeffQuo, INTERVAL_VECTOR &CoeffRem)The polynomial of degree Degree with cofficients Coeff will be divided by the polynomial of degree DegreeDivisor with coefficients CoeffDivisor so that the coefficient will be a polynomial of degree Degree-DegreeDivisor with coefficients CoeffQuo with a reminder which is a polynomial of degree DegreeDivisor and coefficients CoeffRem. This procedure returns 0 if the division is not possible (the interval coefficient of the leading term of includes 0) or if the degree of is greater than the degree of . If the division has been performed this procedure will return 1.
Note that Divide_Polynom and Divide_Evaluate_Multiple may be used to perform the deflation of an univariate polynomial as soon as approximate roots for the polynomial have been found. This may be useful to decrease the computation time for solving a polynomial or for numerically instable polynomial such as the Wilkinson polynomial. A combination of Rouche filtering and of deflation allows to solve Wilkinson polynomial of order 18, while the general solving procedure will fail starting at order 13.
A special Euclidian division is the division of a polynomial by its derivative. This can be done with
void Quotient_UP_Derivative(int Degree,VECTOR &Coeff,VECTOR &CoeffD,VECTOR &Quo, VECTOR &Rem)where has coefficients Coeff, its derivative CoeffD and the coefficient of the division is Quo (the quotient is a polynomial of degree 1) while the coefficients of the remainder are stored in Rem
The coefficients of the expansion of the polynomial may be obtained with the procedure
INTERVAL_VECTOR Power_Polynomial(INTERVAL &a,int n)which returns the coefficients
Let which may also be written as where is some fixed or interval value. The coefficient may be calculated with the procedure
int Derive_Polynomial_Expansion(int n,INTERVAL_VECTOR &Coeff,INTERVAL &a,INTERVAL_VECTOR &B)which returns 1 if the have been successfully calculated (0 otherwise). The coefficients of are Coeff and the are stored in B.
Let be a polynomial and be maxroot the maximal modulus of the root of . From we may derive a polynomial such that the roots of have a modulus lower or equal to 1 and if is a root of then maxroot is a root of . The calculation of the coefficients of may be done with the procedure
int Unit_Polynom(int Degree,INTERVAL_VECTOR &Coeff, double maxroot,INTERVAL_VECTOR &CoeffU)where Coeff are the coefficients of and CoeffU the coefficients of . This procedure returns 1 if the calculation has been successfull, 0 otherwise.
INTERVAL_VECTOR Evaluate_Coeff_Safe_Interval(int n,VECTOR &Coeff);with:
jean-pierre merlet