// copyright (c) 1997, Thomas C. Hales, all rights reserved. // This and 3d.cc give essential bounds on the second derivatives // of the key functions used in the Kepler conjecture. // This file contains the six dimensional functions such as vorAnalytic, // dih,solid, etc. and 3d.cc contains the three dimensional functions // such as eta, and quoin. // The regions over which the bounds were computed were flat quarters, // upright quarters, and quasi-regular tetrahedra. The output has // been saved in several files out.sec.* and out.dih.*. // This output will be fed into the inequality verifier to give good // Taylor approximations to these functions. // These programs only need to be run once, which is fortunate, because // they take a few days each // compute second derivatives // we assume that multiplication by powers of two is exact, // that unary negation is exact, // and that u*v + (-x)*y gives correct upward rounding (but u*v- x*y does not). #include #include extern "C" { #include #include #include #include } #include "error.h" #include "interval.h" #include "secondDerive.h" /* CLASS Leibniz Some calculus methods including the product and quotient rules. The code is written for functions of 6 variables, but this could be easily modified. OVERVIEW TEXT The class Leibniz contains some calculus methods including the product and quotient rules. It also contains a square root method that computes the derivatives of the square root of a function by the chain rule. AUTHOR Thomas C. Hales */ class Leibniz { public: ////////// // Use the product rule to compute a product uv, its first // derivatives Duv, and its second derivatives DDuv in terms // of the same data for u and v. // // The input is the derivative information for the first function // u, Du, and DDu, and for the second function v, Dv, DDv. // // void is returned because the calculation will always be // successful provided the magnitudes of the numbers involved // are less than DBL_MAX // // It is assumed that the functions are functions of 6 variables. // static void product(const interval& u,const interval Du[6], const interval DDu[6][6], const interval& v,const interval Dv[6],const interval DDv[6][6], interval& uv,interval Duv[6],interval DDuv[6][6]); ////////// // Use the chain rule to compute the sqrt of a function, and // its first and second derivatives in terms of the same data // for the function // // The input is the value and derivative information of the // first function u, Du, DDu. // The return is sqrt_u, Dsqrt_u, DDsqrt_u containing the // square root information. // // If calculation is not sucessful, 0 is returned, otherwise // a nonzero is returned. The squrt_u variables take undefined // values if the calculation is not a success. // This function should be safe to // call even if u is not strictly positive, but no useful // information will be obtained. // // It is assumed that the functions are functions of 6 variables. // static int Dsqrt(const interval&u,const interval Du[6],const interval DDu[6][6], interval& sqrt_u,interval Dsqrt_u[6],interval DDsqrt_u[6][6]); ////////// // Use the quotient rule to compute a quotient v=a/b, its first // derivatives Dv, and its second derivatives DDv in terms // of the same data for a and b. // // The input is the derivative information for the first function // a, Da, and DDa, and for the second function b, Db, DDb. // // If the computation is a sucess a nonzero integer is returned. // The usual cause of an unsuccesful call is a zero denominator. // An effort is made to avoid a division by zero. If this appears // likely an unsucessful return is made. // // It is assumed that the functions are functions of 6 variables. // static int quotient(const interval& a,const interval Da[6], const interval DDa[6][6], const interval& b,const interval Db[6],const interval DDb[6][6], interval& v,interval Dv[6],interval DDv[6][6]); }; // pretty printing of intervals.... class band { public: double ymin; double ymax; friend ostream &operator<< (ostream &stream,band c); band(interval x) {ymin = interMath::inf(x); ymax = interMath::sup(x); } }; ostream &operator<< (ostream &stream,band c) { stream << "{" << c.ymin << "," << c.ymax << "}; "; return stream; } static void print(interval f,const interval Df[6],const interval DDf[6][6]) { int i,j; cout << "f = " << f << endl << "Df = "; for (i=0;i<6;i++) cout << Df[i] << " "; cout << endl << "DDf = {"; for (i=0;i<6;i++) { cout << "{"; for (j=0;j<6;j++) cout << DDf[i][j].lo << (j<5? ",": " ") ; cout << "}" << (i<5 ?"," :"}") << endl; } cout << flush; } static inline double max(double x,double y) { return (x > y ? x : y); } static inline double min(double x,double y) { return (x > y ? y : x); } static void array_multiply(interval a,const interval Df[6][6], interval aDf[6][6]) { int i,j; if (interMath::inf(a) > 0.0) { interMath::up(); for (i=0;i<6;i++) for (j=0;j<6;j++) (Df[i][j].hi < 0.0 ? aDf[i][j].hi = Df[i][j].hi*a.lo : aDf[i][j].hi = Df[i][j].hi*a.hi); interMath::down(); for (i=0;i<6;i++) for (j=0;j<6;j++) (Df[i][j].lo > 0.0 ? aDf[i][j].lo = Df[i][j].lo*a.lo : aDf[i][j].lo = Df[i][j].lo*a.hi); } else if (interMath::sup(a) < 0.0) { interMath::up(); for (i=0;i<6;i++) for (j=0;j<6;j++) (Df[i][j].lo < 0.0 ? aDf[i][j].hi = Df[i][j].lo*a.lo : aDf[i][j].hi = Df[i][j].lo*a.hi); interMath::down(); for (i=0;i<6;i++) for (j=0;j<6;j++) (Df[i][j].hi > 0.0 ? aDf[i][j].lo = Df[i][j].hi*a.lo: aDf[i][j].lo = Df[i][j].hi*a.hi); } else { interMath::up(); for (i=0;i<6;i++) for (j=0;j<6;j++) if (Df[i][j].lo > 0.0) aDf[i][j].hi = Df[i][j].hi*a.hi; else if (Df[i][j].hi < 0.0) aDf[i][j].hi = Df[i][j].lo*a.lo; else aDf[i][j].hi = max(a.lo*Df[i][j].lo,a.hi*Df[i][j].hi); interMath::down(); for (i=0;i<6;i++) for (j=0;j<6;j++) if (Df[i][j].lo > 0.0) aDf[i][j].lo = Df[i][j].hi*a.lo; else if (Df[i][j].hi < 0.0) aDf[i][j].lo = Df[i][j].lo*a.hi; else aDf[i][j].lo = min(a.lo*Df[i][j].hi,a.hi*Df[i][j].lo); } } static void half_array_multiply(interval a,const interval Df[6][6], interval aDf[6][6]) { int i,j; if (interMath::inf(a) > 0.0) { interMath::up(); for (i=0;i<6;i++) for (j=i;j<6;j++) (Df[i][j].hi < 0.0 ? aDf[i][j].hi = Df[i][j].hi*a.lo : aDf[i][j].hi = Df[i][j].hi*a.hi); interMath::down(); for (i=0;i<6;i++) for (j=i;j<6;j++) (Df[i][j].lo > 0.0 ? aDf[i][j].lo = Df[i][j].lo*a.lo : aDf[i][j].lo = Df[i][j].lo*a.hi); } else if (interMath::sup(a) < 0.0) { interMath::up(); for (i=0;i<6;i++) for (j=i;j<6;j++) (Df[i][j].lo < 0.0 ? aDf[i][j].hi = Df[i][j].lo*a.lo : aDf[i][j].hi = Df[i][j].lo*a.hi); interMath::down(); for (i=0;i<6;i++) for (j=i;j<6;j++) (Df[i][j].hi > 0.0 ? aDf[i][j].lo = Df[i][j].hi*a.lo: aDf[i][j].lo = Df[i][j].hi*a.hi); } else { interMath::up(); for (i=0;i<6;i++) for (j=i;j<6;j++) if (Df[i][j].lo > 0.0) aDf[i][j].hi = Df[i][j].hi*a.hi; else if (Df[i][j].hi < 0.0) aDf[i][j].hi = Df[i][j].lo*a.lo; else aDf[i][j].hi = max(a.lo*Df[i][j].lo,a.hi*Df[i][j].hi); interMath::down(); for (i=0;i<6;i++) for (j=i;j<6;j++) if (Df[i][j].lo > 0.0) aDf[i][j].lo = Df[i][j].hi*a.lo; else if (Df[i][j].hi < 0.0) aDf[i][j].lo = Df[i][j].lo*a.hi; else aDf[i][j].lo = min(a.lo*Df[i][j].hi,a.hi*Df[i][j].lo); } } /* We use the formula for each third of a Voronoi volume from I.8.6.3: [x1 (x2+x6-x1)+ x2(x1+x6-x2)] chi(x4,x5,x3,x1,x2,x6)/[ 48 u(x1,x2,x6) delta(x1,..x6)^0.5 ] Write this as a product a/b, a = f1 chi; b = 48 u delta^0.5 */ static void setF126(const double x[6],const double z[6], interval& f, interval Df[6], interval DDf[6][6]) { double vmin, vmax, xmin[6], xmax[6]; double xxmin[6][6], xxmax[6][6]; double xa[6],za[6]; int i,j; for (i=0;i<6;i++) for (j=0;j<6;j++) { xxmin[i][j]=0.0; xxmax[i][j]=0.0; } for (i=0;i<6;i++) { xmin[i]=0.0; xmax[i]=0.0; } xxmin[0][0]=xxmax[0][0]=xxmin[1][1]=xxmax[1][1]= -2.0; xxmin[0][1]=xxmax[0][1]=xxmin[1][0]=xxmax[1][0]= 2.0; xxmin[0][5]=xxmax[0][5]=xxmin[1][5]=xxmax[1][5]= 1.0; xxmin[5][0]=xxmax[5][0]=xxmin[5][1]=xxmax[5][1]= 1.0; interMath::down(); xmin[0]=-2.0*z[0] + 2.0*x[1] + x[5]; xmin[1]= 2.0*x[0] - 2.0*z[1] + x[5]; xmin[5]= x[0]+x[1]; interMath::up(); xmax[0]= -2.0*x[0] + 2.0*z[1] + z[5]; xmax[1]= 2.0*z[0] - 2.0*x[1] + z[5]; xmax[5]= z[0]+z[1]; // compute function max; for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) xa[i]=za[i]; else if (xmax[i]<=0.0) za[i]=xa[i]; } // rounding mode is still up. vmax = 2.0*za[0]*za[1] + za[0]*za[5] + za[1]*za[5] + (-xa[0])*xa[0] + (-xa[1])*xa[1]; for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) za[i]=xa[i]; else if (xmax[i]<=0.0) xa[i]=za[i]; } interMath::down(); vmin = 2.0*xa[0]*xa[1] + xa[0]*xa[5] + xa[1]*xa[5] + (-za[0])*za[0] + (-za[1])*za[1]; f = interval(vmin,vmax); for (i=0;i<6;i++) Df[i]=interval(xmin[i],xmax[i]); for (i=0;i<6;i++) for (j=0;j<6;j++) DDf[i][j]=interval(xxmin[i][j],xxmax[i][j]); } static void setChi126(const double x[6],const double z[6], interval& f,interval Df[6],interval DDf[6][6]) { double vmin, vmax, xmin[6], xmax[6], xxmin[6][6], xxmax[6][6]; double xa[6],za[6]; int i,j; for (i=2;i<6;i++) for (j=0;j<6;j++) xxmin[i][j]=xxmax[i][j]=0.0; //^ 2 here because others are initialized. interMath::down(); xxmin[0][0]= -2.0*z[3]; xxmin[0][1]= x[3]+x[4]-2.0*z[5]; xxmin[0][2]= x[5]; xxmin[0][3]= -2.0*z[0]+x[1]+x[5]; xxmin[0][4]= x[1]; xxmin[0][5]= -2.0*z[1] + x[2]+x[3]; xxmin[1][1]= -2.0*z[4]; xxmin[1][2]= x[5]; xxmin[1][3]= x[0]; xxmin[1][4]= x[0]- 2.0*z[1] + x[5]; xxmin[1][5]= -2.0*z[0] +x[2]+x[4]; xxmin[2][5]= x[0]+x[1]-2.0*z[5]; xxmin[3][5]= x[0]; xxmin[4][5]= x[1]; xxmin[5][5]= -2.0*z[2]; interMath::up(); xxmax[0][0]= -2.0*x[3]; xxmax[0][1]= z[3]+z[4]-2.0*x[5]; xxmax[0][2]= z[5]; xxmax[0][3]= -2.0*x[0]+z[1]+z[5]; xxmax[0][4]= z[1]; xxmax[0][5]=-2.0*x[1]+z[2]+z[3]; xxmax[1][1]= -2.0*x[4]; xxmax[1][2]= z[5]; xxmax[1][3]= z[0]; xxmax[1][4]= z[0]- 2.0*x[1] + z[5]; xxmax[1][5] = -2.0*x[0]+z[2]+z[4]; xxmax[2][5]=z[0]+z[1]-2.0*x[5]; xxmax[3][5]= z[0]; xxmax[4][5]=z[1]; xxmax[5][5]=-2.0*x[2]; for (i=0;i<6;i++) for (j=0;j=0.0) xa[i]=za[i]; else if (xxmax[j][i]<=0.0) za[i]=xa[i]; } switch (j) { case 0: xmax[j]= 2.0*(-xa[0])*xa[3]+ za[1]*za[3]+za[1]*za[4] + 2.0*(-xa[1])*xa[5] + za[2]*za[5]+za[3]*za[5]; break; case 1: xmax[j]= za[0]*za[3]+za[0]*za[4]+2.0*(-xa[1])*xa[4] +2.0*(-xa[0])*xa[5]+za[2]*za[5]+za[4]*za[5]; break; case 2: xmax[j]= za[0]*za[5]+za[1]*za[5]+(-xa[5])*xa[5]; break; case 3: xmax[j]= xa[0]*(-xa[0])+za[0]*za[1]+za[0]*za[5]; break; case 4: xmax[j]= za[0]*za[1]+(-xa[1])*xa[1]+za[1]*za[5]; break; case 5: xmax[j]= 2.0*(-xa[0])*xa[1]+za[0]*za[2]+za[1]*za[2] +za[0]*za[3]+za[1]*za[4]+2.0*(-xa[2])*xa[5]; break; } } interMath::down(); // now for xmin[j] for (j=0;j<6;j++) { for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xxmin[j][i]>=0.0) za[i]=xa[i]; else if (xxmax[j][i]<=0.0) xa[i]=za[i]; } switch (j) { case 0: xmin[j]= 2.0*(-za[0])*za[3] + xa[1]*xa[3]+xa[1]*xa[4] +2.0*((-za[1])*za[5]) + xa[2]*xa[5]+xa[3]*xa[5]; break; case 1: xmin[j]= xa[0]*xa[3]+xa[0]*xa[4]+2.0*(-za[1])*za[4] +2.0*(-za[0])*za[5]+xa[2]*xa[5]+xa[4]*xa[5]; break; case 2: xmin[j]= xa[0]*xa[5]+xa[1]*xa[5]+(-za[5])*za[5]; break; case 3: xmin[j]= za[0]*(-za[0])+xa[0]*xa[1]+xa[0]*xa[5]; break; case 4: xmin[j]= xa[0]*xa[1]+(-za[1])*za[1]+xa[1]*xa[5]; break; case 5: xmin[j]= 2.0*(-za[0])*za[1]+xa[0]*xa[2]+xa[1]*xa[2] +xa[0]*xa[3]+xa[1]*xa[4]+2.0*(-za[2])*za[5]; break; } } // now for vmax interMath::up(); for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) xa[i]=za[i]; else if (xmax[i]<=0.0) za[i]=xa[i]; } vmax = (xa[0]*(-xa[0]))*xa[3]+za[0]*za[1]*za[3]+za[0]*za[1]*za[4] + ((-xa[1])*xa[1])*xa[4]+2.0*((-xa[0])*xa[1])*xa[5]+za[0]*za[2]*za[5] + za[1]*za[2]*za[5]+za[0]*za[3]*za[5]+za[1]*za[4]*za[5] +((-xa[2])*xa[5])*xa[5]; interMath::down(); for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) za[i]=xa[i]; else if (xmax[i]<=0.0) xa[i]=za[i]; } vmin = za[0]*((-za[0])*za[3])+xa[0]*xa[1]*xa[3]+xa[0]*xa[1]*xa[4] +((-za[1])*za[1])*za[4]+2.0*((-za[0])*za[1])*za[5] +xa[0]*xa[2]*xa[5] + xa[1]*xa[2]*xa[5]+xa[0]*xa[3]*xa[5]+xa[1]*xa[4]*xa[5] +((-za[2])*za[5])*za[5]; f = interval(vmin,vmax); for (i=0;i<6;i++) Df[i]=interval(xmin[i],xmax[i]); for (i=0;i<6;i++) for (j=0;j<6;j++) DDf[i][j]=interval(xxmin[i][j],xxmax[i][j]); } // end of setChi126; int secondDerive::setChi126(const double x[6],const double z[6],interval DDf[6][6]) { interval f,Df[6]; ::setChi126(x,z,f,Df,DDf); return 1; } static void setU126(const double x[6],const double z[6], interval& f, interval Df[6], interval DDf[6][6]) { double vmin, vmax, xmin[6], xmax[6], xxmin[6][6], xxmax[6][6]; double xa[6],za[6]; int i,j; for (i=0;i<6;i++) for (j=0;j<6;j++) { xxmin[i][j]=0.0; xxmax[i][j]=0.0; } for (i=0;i<6;i++) { xmin[i]=0.0; xmax[i]=0.0; } xxmin[0][0]=xxmax[0][0]=xxmin[1][1]=xxmax[1][1]= -2.0; xxmin[5][5]=xxmax[5][5]= -2.0; xxmin[0][1]=xxmax[0][1]=xxmin[1][0]=xxmax[1][0]= 2.0; xxmin[0][5]=xxmax[0][5]=xxmin[1][5]=xxmax[1][5]= 2.0; xxmin[5][0]=xxmax[5][0]=xxmin[5][1]=xxmax[5][1]= 2.0; interMath::down(); xmin[0]= 2.0*(-z[0] + x[1] + x[5]); xmin[1]= 2.0*(-z[1] + x[0] + x[5]); xmin[5]= 2.0*(-z[5] + x[0] + x[1]); interMath::up(); xmax[5]= 2.0*(-x[5] + z[0] + z[1]); xmax[0]= 2.0*(-x[0] + z[1] + z[5]); xmax[1]= 2.0*(-x[1] + z[0] + z[5]); // compute function max; still in up mode: for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) xa[i]=za[i]; else if (xmax[i]<=0.0) za[i]=xa[i]; } vmax = xa[0]*(-xa[0])+(-xa[1])*xa[1]+(-xa[5])*xa[5]+ 2.0*(za[0]*za[1]+za[1]*za[5]+za[5]*za[0]); interMath::down(); for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) za[i]=xa[i]; else if (xmax[i]<=0.0) xa[i]=za[i]; } vmin = za[0]*(-za[0])+(-za[1])*za[1]+(-za[5])*za[5]+ 2.0*(xa[0]*xa[1]+xa[1]*xa[5]+xa[5]*xa[0]); f = interval(vmin,vmax); for (i=0;i<6;i++) Df[i]=interval(xmin[i],xmax[i]); for (i=0;i<6;i++) for (j=0;j<6;j++) DDf[i][j]=interval(xxmin[i][j],xxmax[i][j]); } int secondDerive::setU126(const double x[6],const double z[6], interval DDf[6][6]) { interval f,Df[6]; ::setU126(x,z,f,Df,DDf); return 1; } void setU135(const double x[6],const double z[6], interval& f, interval Df[6], interval DDf[6][6]) { double xx[6] = {x[0],x[2],x[1],x[3],x[5],x[4]}; double zz[6] = {z[0],z[2],z[1],z[3],z[5],z[4]}; interval Dg[6],DDg[6][6]; ::setU126(xx,zz,f,Dg,DDg); int k[6]={0,2,1,3,5,4}; int i,j; for (i=0;i<6;i++) Df[i]=Dg[k[i]]; for (i=0;i<6;i++) for (j=0;j<6;j++) DDf[i][j]=DDg[k[i]][k[j]]; } int secondDerive::setU135(const double x[6],const double z[6], interval DDf[6][6]) { interval f,Df[6]; ::setU135(x,z,f,Df,DDf); return 1; } // a = Sqrt[x1 x2 x3] + (x2+x3-x4)Sqrt[x1]/2 + (x1+x3-x5)Sqrt[x2]/2 + // (x1+x2-x6)Sqrt[x3]/2; static int setA(const double x[6],const double z[6], interval& f, interval Df[6], interval DDf[6][6]) { double vmin, vmax, xmin[6], xmax[6], xxmin[6][6], xxmax[6][6]; int i,j; for (i=0;i<6;i++) for (j=0;j<6;j++) xxmin[i][j]=xxmax[i][j]=0.0; double tx,tz,sqz,sqx; double hn0,hn1,hn2,hu0,hu1,hu2; interval y[3],xx[6]; for (i=0;i<6;i++) xx[i]=interval(x[i],z[i]); for (i=0;i<3;i++) y[i]=interMath::sqrt(xx[i]); interMath::up(); sqz= (interMath::sup(y[0]))*(interMath::sup(y[1]))*(interMath::sup(y[2])); interMath::down(); sqx= (interMath::inf(y[0]))*(interMath::inf(y[1]))*(interMath::inf(y[2])); if ((sqz=0.0) xa[i]=za[i]; else if (xxmax[j][i]<=0.0) za[i]=xa[i]; } switch (j) { case 0: xmax[j]= 2.0*(-xa[0])*xa[3]+za[1]*za[3]+za[2]*za[3] +(-xa[3])*xa[3]+za[1]*za[4]+(-xa[2])*xa[4] +za[3]*za[4]+(-x[1])*x[5]+za[2]*za[5] +za[3]*za[5]; break; case 1: xmax[j]= za[4]*(za[0]+za[2]+za[3]+za[5]) +(-xa[4])*xa[1]+(-xa[4])*xa[4] +(-xa[2])*xa[3]+(-xa[1])*xa[4]+(-xa[0])*xa[5] +za[0]*za[3]+za[2]*za[5]; break; case 2: xmax[j]= za[5]*(za[0]+za[1]+za[3]+za[4]) +za[0]*za[3]+za[1]*za[4] +(-xa[5])*xa[2]+(-xa[5])*xa[5] +(-xa[1])*xa[3]+(-xa[0])*xa[4]+(-xa[2])*xa[5]; break; case 3: xmax[j]= za[0]*(za[1]+za[2]+za[4]+za[5]) + za[1]*za[4]+za[2]*za[5] +(-xa[0])*xa[0]+(-xa[0])*xa[3] +(-xa[1])*xa[2]+(-xa[0])*xa[3]+(-xa[4])*xa[5]; break; case 4: xmax[j]= za[1]*(za[0]+za[2]+za[3]+za[5]) + za[0]*za[3]+za[2]*za[5] +(-xa[1])*xa[1]+(-xa[1])*xa[4] +(-xa[0])*xa[2]+(-xa[1])*xa[4]+(-xa[3])*xa[5]; break; case 5: xmax[j]= za[2]*(za[0]+za[1]+za[3]+za[4]) + za[0]*za[3]+za[1]*za[4] +(-xa[2])*xa[2]+(-xa[2])*xa[5] +(-xa[0])*xa[1]+(-xa[3])*xa[4]+(-xa[2])*xa[5]; break; } } interMath::down(); // now for xmin[j] for (j=0;j<6;j++) { for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xxmin[j][i]>=0.0) za[i]=xa[i]; else if (xxmax[j][i]<=0.0) xa[i]=za[i]; } switch (j) { case 0: xmin[j]= 2.0*(-za[0])*za[3]+xa[1]*xa[3]+xa[2]*xa[3] +(-za[3])*za[3]+xa[1]*xa[4]+(-za[2])*za[4] +xa[3]*xa[4]+(-z[1])*z[5]+xa[2]*xa[5] +xa[3]*xa[5]; break; case 1: xmin[j]= xa[4]*(xa[0]+xa[2]+xa[3]+xa[5]) +(-za[4])*za[1]+(-za[4])*za[4] +(-za[2])*za[3]+(-za[1])*za[4]+(-za[0])*za[5] +xa[0]*xa[3]+xa[2]*xa[5]; break; case 2: xmin[j]= xa[5]*(xa[0]+xa[1]+xa[3]+xa[4]) +xa[0]*xa[3]+xa[1]*xa[4] +(-za[5])*za[2]+(-za[5])*za[5] +(-za[1])*za[3]+(-za[0])*za[4]+(-za[2])*za[5]; break; case 3: xmin[j]= xa[0]*(xa[1]+xa[2]+xa[4]+xa[5]) + xa[1]*xa[4]+xa[2]*xa[5] +(-za[0])*za[0]+(-za[0])*za[3] +(-za[1])*za[2]+(-za[0])*za[3]+(-za[4])*za[5]; break; case 4: xmin[j]= xa[1]*(xa[0]+xa[2]+xa[3]+xa[5]) + xa[0]*xa[3]+xa[2]*xa[5] +(-za[1])*za[1]+(-za[1])*za[4] +(-za[0])*za[2]+(-za[1])*za[4]+(-za[3])*za[5]; break; case 5: xmin[j]= xa[2]*(xa[0]+xa[1]+xa[3]+xa[4]) + xa[0]*xa[3]+xa[1]*xa[4] +(-za[2])*za[2]+(-za[2])*za[5] +(-za[0])*za[1]+(-za[3])*za[4]+(-za[2])*za[5]; break; } } interMath::up(); // now for vmax for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) xa[i]=za[i]; else if (xmax[i]<=0.0) za[i]=xa[i]; } vmax = (xa[1]*(-xa[2]))*xa[3]+ ((-xa[0])*xa[2])*xa[4] +((-xa[0])*xa[1])*xa[5] +((-xa[3])*xa[4])*xa[5] +za[2]*za[5]*(za[0]+za[1]+za[3]+za[4]) +((-xa[2])*xa[5])*xa[2]+((-xa[2])*xa[5])*xa[5] +za[1]*za[4]*(za[0]+za[2]+za[3]+za[5]) +((-xa[1])*xa[4])*xa[1]+((-xa[1])*xa[4])*xa[4] +za[0]*za[3]*(za[1]+za[2]+za[4]+za[5]) +((-xa[0])*xa[3])*xa[0]+((-xa[0])*xa[3])*xa[3]; for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (xmin[i]>=0.0) za[i]=xa[i]; else if (xmax[i]<=0.0) xa[i]=za[i]; } interMath::down(); vmin = (za[1]*(-za[2]))*za[3]+((-za[0])*za[2])*za[4] +((-za[0])*za[1])*za[5] +((-za[3])*za[4])*za[5] +xa[2]*xa[5]*(xa[0]+xa[1]+xa[3]+xa[4]) +((-za[2])*za[5])*za[2]+((-za[2])*za[5])*za[5] +xa[1]*xa[4]*(xa[0]+xa[2]+xa[3]+xa[5]) +((-za[1])*za[4])*za[1]+((-za[1])*za[4])*za[4] +xa[0]*xa[3]*(xa[1]+xa[2]+xa[4]+xa[5]) +((-za[0])*za[3])*za[0]+((-za[0])*za[3])*za[3]; f = interval(vmin,vmax); for (i=0;i<6;i++) Df[i]=interval(xmin[i],xmax[i]); for (i=0;i<6;i++) for (j=0;j<6;j++) DDf[i][j]=interval(xxmin[i][j],xxmax[i][j]); } // end of setDelta; int secondDerive::setDelta(const double x[6],const double z[6],interval DDf[6][6]) { interval f,Df[6]; ::setDelta(x,z,f,Df,DDf); return 1; } int secondDerive::setChi2over4uDelta(const double x[6],const double z[6],double DDf[6][6]) { // this + eta^2 126 is the circumradius squared of a simplex. int i,j; interval d,Dd[6],DDd[6][6]; interval c,Dc[6],DDc[6][6]; interval u,Du[6],DDu[6][6]; ::setDelta(x,z,d,Dd,DDd); ::setChi126(x,z,c,Dc,DDc); ::setU126(x,z,u,Du,DDu); if (interMath::inf(u)<=1.0e-5) return 0; if (interMath::inf(d)<=1.0e-5) return 0; interval c2,Dc2[6],DDc2[6][6]; Leibniz::product(c,Dc,DDc,c,Dc,DDc,c2,Dc2,DDc2); interval den,Dden[6],DDden[6][6]; Leibniz::product(u,Du,DDu,d,Dd,DDd,den,Dden,DDden); interval q,Dq[6],DDq[6][6]; if (!Leibniz::quotient(c2,Dc2,DDc2,den,Dden,DDden,q,Dq,DDq)) return 0; for (i=0;i<6;i++) for (j=i;j<6;j++) DDf[i][j]= interMath::sup(interMath::max(DDq[i][j],-DDq[i][j]))/4.0; for (i=0;i<6;i++) for (j=0;j=0.0) xa[i]=za[i]; else if (interMath::sup(Df[i])<=0.0) za[i]=xa[i]; } vmax = xa[1]*(-xa[2])+(-xa[0])*xa[3] +za[1]*za[4]+za[2]*za[5] +(-xa[4])*xa[5] +za[0]*(za[1]+za[2]+za[4]+za[5]) +(-xa[0])*xa[0]+(-xa[0])*xa[3]; interMath::down(); for (i=0;i<6;i++) { xa[i]=x[i]; za[i]=z[i]; if (interMath::inf(Df[i])>=0.0) za[i]=xa[i]; else if (interMath::sup(Df[i])<=0.0) xa[i]=za[i]; } vmin = za[1]*(-za[2])+ (-za[0])*za[3]+xa[1]*xa[4]+xa[2]*xa[5]+(-za[4])*za[5] + xa[0]*(xa[1]+xa[2]+xa[4]+xa[5]) +(-za[0])*za[0]+(-za[0])*za[3]; f = interval(vmin,vmax); } // now start building up more complex functions with the product rule, etc. void Leibniz::product(const interval& u,const interval Du[6],const interval DDu[6][6], const interval& v,const interval Dv[6],const interval DDv[6][6], interval& uv,interval Duv[6],interval DDuv[6][6]) { int i,j; uv = u*v; for (i=0;i<6;i++) Duv[i] = u*Dv[i] + v*Du[i]; interval DuDv[6][6]; for (i=0;i<6;i++) for (j=0;j<6;j++) DuDv[i][j]=Du[i]*Dv[j]; interval uDDv[6][6],vDDu[6][6]; half_array_multiply(v,DDu,vDDu); half_array_multiply(u,DDv,uDDv); for (i=0;i<6;i++) for (j=i;j<6;j++) DDuv[i][j]= uDDv[i][j]+DuDv[i][j]+DuDv[j][i]+vDDu[i][j]; for (i=0;i<6;i++) for (j=0;j -smallDen)) return 0; v = a/b; interval b2 = one/(b*b); interval t = -two*b2/b; interval r[6]; for (i=0;i<6;i++) r[i] = (Da[i]*b- a*Db[i]); for (i=0;i<6;i++) Dv[i] = r[i]*b2; for (i=0;i<6;i++) r[i] = r[i]*t; interval DaDb[6][6]; for (i=0;i<6;i++) for (j=0;j<6;j++) DaDb[i][j]=Da[i]*Db[j]; interval bDDa[6][6]; half_array_multiply(b,DDa,bDDa); interval aDDb[6][6]; half_array_multiply(a,DDb,aDDb); interval DDu[6][6]; for (i=0;i<6;i++) for (j=i;j<6;j++) DDu[i][j]= (bDDa[i][j]+DaDb[i][j]-DaDb[j][i]-aDDb[i][j]); half_array_multiply(b2,DDu,DDv); for (i=0;i<6;i++) for (j=i;j<6;j++) DDv[i][j] = DDv[i][j] + r[i]*Db[j]; for (i=0;i<6;i++) for (j=0;j=0.0)) return 0; if ((interMath::inf(u135)<=0.0)&&(interMath::sup(u135)>=0.0)) return 0; if ((interMath::inf(u126)<=0.0)&&(interMath::sup(u126)>=0.0)) return 0; h = pi2+ interMath::atan(-dX/b); for (i=0;i<6;i++) Db[i]= Ds[i]*ty1; interval ry1 = two/ty1; Db[0] = Db[0]+ s*ry1; interval c[6]; for (i=0;i<6;i++) c[i]= -DdX[i]*b + dX*Db[i]; interval ru = one/(u135*u126); for (i=0;i<6;i++) Dh[i]= c[i]*ru; Dh[3]= ty1/(two*s); interval ru126 = one/u126; interval ru135 = one/u135; for (i=0;i<6;i++) for (j=i;j<6;j++) DDb[i][j]= DDs[i][j]*ty1; for (i=1;i<6;i++) DDb[0][i] = DDb[0][i] + Ds[i]*ry1; DDb[0][0] = DDb[0][0] + two*Ds[0]*ry1 - s*ry1/interval(2.0*x[0],2.0*z[0]); interval U[6]; for (i=0;i<6;i++) U[i]= Du135[i]*ru135+Du126[i]*ru126; interval bDDdX[6][6]; half_array_multiply(b,DDdX,bDDdX); interval XDDb[6][6]; half_array_multiply(dX,DDb,XDDb); for (i=0;i<6;i++) for (j=i+1;j<6;j++) DDh[i][j]= ru*(-bDDdX[i][j] - DdX[i]*Db[j] + DdX[j]*Db[i] + XDDb[i][j]) - Dh[i]*U[j]; for (i=0;i<6;i++) DDh[i][i]= ru*(-bDDdX[i][i]+ XDDb[i][i]) - Dh[i]*U[i]; for (i=0;i<6;i++) for (j=0;j= interMath::sup(twicet)) { r=Dr=DDr=zero; return 1; } if ((interMath::inf(xxq)<=0.0)&& (interMath::sup(xxq)>=0.0)) return 0; static const interval dt = "0.7209029495174650928412448"; // doct static const interval dt12 = "0.06007524579312209107010373625"; //doct/12; interval dtt2 = dt*t2; static const interval N16("16"); static const interval N8("8"); DDr = dtt2/(four*xxq) + dt/(N16*q); Dr = -dtt2/(two*q) + dt*q/N8; r = (four*dtt2*t)/three - dtt2*q + dt12*xxq; if (qu>interMath::inf(twicet)) { r = interMath::combine(r,zero); Dr=interMath::combine(Dr,zero); DDr=interMath::combine(DDr,zero); } return 1; } //////// // // Adih = A[y1/2] dih(S). // Adih = Adihfactor*dih. // int Adih(double x,double z,interval trunc, const interval& d,const interval Dd[6],const interval DDd[6][6], interval DDc[6][6]) { interval r,Dr,DDr; if (!(Adihfactor(x,z,trunc,r,Dr,DDr))) return 0; int i,j; for (i=0;i<6;i++) for (j=i;j<6;j++) DDc[i][j] = r*DDd[i][j]; for (i=0;i<6;i++) for (j=0;jinterMath::sup(s63))|| (z[1]>interMath::sup(s63))|| (z[2]>interMath::sup(s63))) return 0; // because out.quoin.simplex.sqrt is used. interval s,Ds[6],DDs[6][6]; interval DDf1[6][6],DDf2[6][6],DDf3[6][6],DDx[6][6]; interval f,Df[6]; interval DDx1[6][6],DDx2[6][6],DDx3[6][6]; if (!setSqrtDelta(x,z,s,Ds,DDs)) return 0; if (!setDihedral(x,z,s,Ds,DDs,f,Df,DDf1)) return 0; if (!Adih(x[0],z[0],t, f,Df,DDf1,DDx1)) return 0; if (!setDih2(x,z,s,Ds,DDs,f,Df,DDf2)) return 0; if (!Adih2(x[1],z[1],t, f,Df,DDf2,DDx2)) return 0; if (!setDih3(x,z,s,Ds,DDs,f,Df,DDf3)) return 0; if (!Adih3(x[2],z[2],t, f,Df,DDf3,DDx3)) return 0; for (i=0;i<6;i++) for (j=i;j<6;j++) { DDx[i][j]=DDx1[i][j]+DDx2[i][j]+DDx3[i][j]+ (DDf1[i][j]+DDf2[i][j]+DDf3[i][j])*tildeV; } static const interval diag = two*interval::wideInterval("-0.192","0.192")*doct4; // diag max abs = 0.147748... // from out.quoin.simplex.sqrt; if (x[5]<=8.0) { DDx[0][1] = DDx[0][1]+tdoct4quoin; DDx[1][5] = DDx[1][5]+tdoct4quoin; DDx[0][5] = DDx[0][5]+tdoct4quoin; DDx[0][0] = DDx[0][0]+diag; DDx[1][1] = DDx[1][1]+diag; DDx[5][5] = DDx[5][5]+diag; } if (x[4]<=8.0) { DDx[0][2] = DDx[0][2]+tdoct4quoin; DDx[0][4] = DDx[0][4]+tdoct4quoin; DDx[2][4] = DDx[2][4]+tdoct4quoin; DDx[0][0] = DDx[0][0]+diag; DDx[2][2] = DDx[2][2]+diag; DDx[4][4] = DDx[4][4]+diag; } if (x[3]<=8.0) { DDx[1][2] = DDx[1][2]+tdoct4quoin; DDx[1][3] = DDx[1][3]+tdoct4quoin; DDx[2][3] = DDx[2][3]+tdoct4quoin; DDx[1][1] = DDx[1][1]+diag; DDx[4][4] = DDx[4][4]+diag; DDx[3][3] = DDx[3][3]+diag; } for (i=0;i<6;i++) for (j=0;jinterMath::sup(s63))||(z[2]>interMath::sup(s63))) { error::message("setVorVc used out of range"); return 0; } interval s,Ds[6],DDs[6][6]; interval DDf1[6][6],DDf2[6][6],DDf3[6][6]; interval f,Df[6]; interval DDx1[6][6],DDx2[6][6],DDx3[6][6]; if (!secondDerive::setSqrtDelta(x,z,s,Ds,DDs)) return 0; if (!secondDerive::setDihedral(x,z,s,Ds,DDs,f,Df,DDf1)) return 0; if (!Adih(x[0],z[0],t, f,Df,DDf1,DDx1)) return 0; if (!secondDerive::setDih2(x,z,s,Ds,DDs,f,Df,DDf2)) return 0; if (!Adih2(x[1],z[1],t, f,Df,DDf2,DDx2)) return 0; if (!secondDerive::setDih3(x,z,s,Ds,DDs,f,Df,DDf3)) return 0; if (!Adih3(x[2],z[2],t, f,Df,DDf3,DDx3)) return 0; for (i=0;i<6;i++) for (j=i;j<6;j++) { DDx[i][j]=DDx1[i][j] +DDx2[i][j]+DDx3[i][j]+ (DDf1[i][j]+DDf2[i][j]+DDf3[i][j])*tildeV; } for (i=0;i<6;i++) for (j=0;jinterMath::sup(s63))||(z[2]>interMath::sup(s63))) { error::message("setVorVc used out of range"); return 0; } interval s,Ds[6],DDs[6][6]; interval DDf1[6][6],DDf2[6][6],DDf3[6][6]; interval f,Df[6]; interval DDx1[6][6],DDx2[6][6],DDx3[6][6]; if (!secondDerive::setSqrtDelta(x,z,s,Ds,DDs)) return 0; if (!secondDerive::setDihedral(x,z,s,Ds,DDs,f,Df,DDf1)) return 0; if (!Adih(x[0],z[0],t, f,Df,DDf1,DDx1)) return 0; if (!secondDerive::setDih2(x,z,s,Ds,DDs,f,Df,DDf2)) return 0; if (!Adih2(x[1],z[1],t, f,Df,DDf2,DDx2)) return 0; if (!secondDerive::setDih3(x,z,s,Ds,DDs,f,Df,DDf3)) return 0; if (!Adih3(x[2],z[2],t, f,Df,DDf3,DDx3)) return 0; for (i=0;i<6;i++) for (j=i;j<6;j++) { DDx[i][j]=DDx1[i][j] +DDx2[i][j]+DDx3[i][j]+ (DDf1[i][j]+DDf2[i][j]+DDf3[i][j])*tildeV; } for (i=0;i<6;i++) for (j=0;jepsilon) { cout << "close : " << interMath::abs(y-interval(x,x)) << " " << y << " " << x << endl<< flush; return 0; } return 1; } static int epsilonClose(double f,double Df[6],double DDf[6][6], interval g,interval Dg[5],interval DDg[6][6],double epsilon) { int i,j; if (!epsilonClose(f,g,epsilon)) { cout << "*" << endl; return 0; } for (i=0;i<6;i++) if (!epsilonClose(Df[i],Dg[i],epsilon)) { cout << i << endl; return 0; } for (i=0;i<6;i++) for (j=0;j<6;j++) if (!epsilonClose(DDf[i][j],DDg[i][j],epsilon)) { cout << i <<" "<1.255, cout.precision(16); double mf =0; double Dmf[6] = {0,0,0,0,0,0}; double DDmf[6][6] = {{0.05399742262145269, 0.001941109611880804, 0.002591451769354967, -0.009341612836680926, 0.007105093042316984, 0.007324402654216028}, {0.001941109611880805, 0.05402015824995872, 0.003150669397111228, 0.006969189493705773, -0.008721458819363622, 0.007351222717650264}, {0.002591451769354965, 0.003150669397111225, 0.05422091663845037, 0.007035629668212111, 0.007200509217801438, -0.008091450771502836}, {-0.009341612836680926, 0.006969189493705773, 0.007035629668212111, 0.00516319753220431, -0.004667265448268399, -0.00458015495504247}, {0.007105093042316984, -0.008721458819363622, 0.007200509217801438, -0.004667265448268399, 0.005267097722808903, -0.004487280153267206}, {0.007324402654216028, 0.007351222717650264, -0.008091450771502833, -0.004580154955042471, -0.004487280153267206, 0.005398344314989866}}; interval DDx[6][6]; setVorVcNoQuoin(z,z,DDx); interval n=zero,Dn[6]={n,n,n,n,n,n}; if (!epsilonClose(mf,Dmf,DDmf,n,Dn,DDx,1.0e-10)) { cout << "VorVcNoQuoin failed: " ; print (n,Dn,DDx); error::message("Second derivatives failed to install properly"); } } /*test setVor1385NoQuoin */ { // constants computed in Mathematica. double z[6]={4.7,4.8,5.1,5.2,5.4,5.7}; // rad(z)>1.385, cout.precision(16); double mf =0; double Dmf[6] = {0,0,0,0,0,0}; double DDmf[6][6] = {{0.0478546308290609, -0.002889268658288134, -0.001273118788492866, -0.007541680741402377, 0.009956516628944605, 0.009948955415732298}, {-0.002889268658288141, 0.04858100332439985, -0.0007824601321044857, 0.01008143637875229, -0.007004856760563882, 0.009969903466756662}, {-0.00127311878849287, -0.0007824601321044823, 0.04906190095094674, 0.009932353325518896, 0.009810297045074584, -0.005359292348280169}, {-0.007541680741402371, 0.01008143637875229, 0.009932353325518894, 0.008504386568552268, -0.007757250400015124, -0.00786228393249746}, {0.009956516628944605, -0.007004856760563884, 0.009810297045074584, -0.007757250400015124, 0.008544510896035715, -0.008006857876453842}, {0.009948955415732301, 0.009969903466756662, -0.005359292348280169, -0.00786228393249746, -0.008006857876453844, 0.009087438534120506}}; interval DDx[6][6]; setVor1385NoQuoin(z,z,DDx); interval n=zero,Dn[6]={n,n,n,n,n,n}; if (!epsilonClose(mf,Dmf,DDmf,n,Dn,DDx,1.0e-10)) { cout << "Vor1385NoQuoin failed: " ; print (n,Dn,DDx); error::message("Second derivatives failed to install properly"); } } /*test setVorVc */ { // constants computed in Mathematica with lineInterval routine. double z[6]={4.2,4.3,4.4,4.5,4.6,4.7}; // rad(z)>1.255, cout.precision(16); //double mf =0; //double Dmf[6] = {0,0,0,0,0,0}; double DDmf[6][6] = // absolute values of data: {{0.04451022565404638, 0.003253033720076057, 0.002967145322222462, 0.009341612836680944, 0.000145986994096521, 0.0004158696512009301}, {0.003253033720076055, 0.04411934782391634, 0.002752283828603631, 0.0001451969147139176, 0.008721458819363625, 0.0003321760267211591}, {0.002967145322222464, 0.002752283828603629, 0.04383305357612751, 0.0002099334785566593, 2.749648354369998e-7, 0.008091450771502849}, {0.009341612836680944, 0.0001451969147139176, 0.0002099334785566602, 0.002234984578078722, 0.004667265448268401, 0.004580154955042468}, {0.0001459869940965228, 0.008721458819363627, 2.749648354369998e-7, 0.004667265448268401, 0.002261097147820291, 0.004487280153267206}, {0.0004158696512009301, 0.0003321760267211582, 0.008091450771502849, 0.004580154955042467, 0.004487280153267206, 0.002276886164839177}}; double DDx[6][6]; interval s=zero,/*Ds[6]={s,s,s,s,s,s},*/ DDs[6][6]; secondDerive::setVorVc(z,z,DDx); for (int i=0;i<6;i++) for (int j=0;j<6;j++) { DDs[i][j]=interval(DDx[i][j],DDx[i][j]); if (interMath::inf(DDs[i][j])1.385, cout.precision(16); //double mf =0; //double Dmf[6] = {0,0,0,0,0,0}; double DDmf[6][6] = // absolute values of data: {{0.03889899498521678, 0.007523143233144931, 0.007165317875469733, 0.007541680741402377, 0.0009378197311457164, 0.001164271193317731}, {0.007523143233144937, 0.03911589910267211, 0.007425269314345619, 0.0005360683799675824, 0.007004856760563882, 0.001103923199169123}, {0.007165317875469736, 0.007425269314345616, 0.03852289468931363, 3.746335451061677e-6, 0.0003551409556477469, 0.005359292348280169}, {0.007541680741402371, 0.0005360683799675824, 3.746335451059942e-6, 0.001594711079555576, 0.007757250400015124, 0.00786228393249746}, {0.0009378197311457164, 0.007004856760563884, 0.0003551409556477453, 0.007757250400015124, 0.001453346107969903, 0.008006857876453842}, {0.001164271193317734, 0.001103923199169123, 0.005359292348280169, 0.00786228393249746, 0.008006857876453844, 0.001436156516679547}}; double DDx[6][6]; interval s=zero,/*Ds[6]={s,s,s,s,s,s},*/ DDs[6][6]; secondDerive::setVor1385(z,z,DDx); for (int i=0;i<6;i++) for (int j=0;j<6;j++) { DDs[i][j]=interval(DDx[i][j],DDx[i][j]); if (interMath::inf(DDs[i][j])sqrt2, cout.precision(16); //double mf =0; //double Dmf[6] = {0,0,0,0,0,0}; double DDmf[6][6] = // absolute values of data: {{0.03779865771267261, 0.008526248758379868, 0.008153674342434429, 0.006150356271165707, 0.002078061534485094, 0.001798102438960657}, {0.008526248758379866, 0.03730624817730242, 0.008123471264883946, 0.001715235789950637, 0.005139529165605567, 0.001366146789444544}, {0.008153674342434429, 0.008123471264883949, 0.03644883102152213, 0.001214466297812393, 0.00115110184311265, 0.004110707818849844}, {0.006150356271165707, 0.001715235789950637, 0.001214466297812391, 0.0001456021154627295, 0.007967130062245022, 0.007945179163991298}, {0.002078061534485092, 0.005139529165605567, 0.00115110184311265, 0.00796713006224502, 0.0001436042779515388, 0.008023844058987206}, {0.001798102438960653, 0.001366146789444544, 0.004110707818849844, 0.007945179163991298, 0.008023844058987206, 0.0000378391999154605}}; double DDx[6][6]; interval s=zero,/*Ds[6]={s,s,s,s,s,s},*/ DDs[6][6]; secondDerive::setVorSqc(z,z,DDx); for (int i=0;i<6;i++) for (int j=0;j<6;j++) { DDs[i][j]=interval(DDx[i][j],DDx[i][j]); if (interMath::inf(DDs[i][j])