// copyright (c) 1997, Thomas C. Hales, all rights reserved. // This and seconds.cc give essential bounds on functions used // in the Kepler conjecture. This file contains the functions // of three variables such as eta and quoin, and seconds.cc contains // the others such as solid,dih,vor_analytic, etc. // The output has been saved in several files out.quoin.* out.eta2. // This will be fed into the inequality verifier to produce good // Taylor approximations to our functions. // This program only needs to be run once, which is fortunate, because // these verifications took a few days each on UofM computers supernova // and blackbox. /* cases caseNum 0 : trunc = 1.255; caseNum 1 : trunc = 1.2584085723648189697; (Sean's) caseNum 2 : trunc = 1.385; caseNum 3 : trunc = sqrt2. */ // 2nd derivative verifications of 3d guys: #include #include #include #include #include "error.h" #include "interval.h" // Modified from 3d.cc on 1/4/98 to allow for other parameters // other than 1.255. // band is used for printing purposes only. // cout << band(interval) is prettier than cout << interval; // copied from io.h,io.cc 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; } // Multiply v by the array DDU and output vDDu. static void half_array_multiply(interval v,const interval DDu[3][3], interval vDDu[3][3]) { int i,j; for (i=0;i<3;i++) for (j=i;j<3;j++) vDDu[i][j] = v*DDu[i][j]; } // Leibniz rule for a three-variable function. // uv, its derivative and second derivatives are output in uv,Duv,DDuv. static void product3(const interval& u,const interval Du[3],const interval DDu[3][3], const interval& v,const interval Dv[3],const interval DDv[3][3], interval& uv,interval Duv[3],interval DDuv[3][3]) { int i,j; uv = u*v; for (i=0;i<3;i++) Duv[i] = u*Dv[i] + v*Du[i]; interval DuDv[3][3]; for (i=0;i<3;i++) for (j=0;j<3;j++) DuDv[i][j]=Du[i]*Dv[j]; interval uDDv[3][3],vDDu[3][3]; half_array_multiply(v,DDu,vDDu); half_array_multiply(u,DDv,uDDv); for (i=0;i<3;i++) for (j=i;j<3;j++) DDuv[i][j]= uDDv[i][j]+DuDv[i][j]+DuDv[j][i]+vDDu[i][j]; for (i=0;i<3;i++) for (j=0;j interMath::inf(tempxx)) eminxx = interMath::inf(tempxx); interval tempxy = eta2xy(x,z); if (emaxxy< interMath::sup(tempxy)) emaxxy = interMath::sup(tempxy); if (eminxy> interMath::inf(tempxy)) eminxy = interMath::inf(tempxy); } // OUTPUT RESULTS. cout.precision(20); cout << identifyingString << endl; cout << "XX: " << eminxx << " " << emaxxx << endl; cout << "XY: " << eminxy << " " << emaxxy << endl; } // OUTER LOOP ENDS. cout << "*" << endl; } // print d,Dd,DDd. static void output3(interval d,interval Dd[3],interval DDd[3][3]) { int i,j; cout << " ----- \n" << band(d) << endl; for (i=0;i<3;i++) cout << i << " " << band(Dd[i]) << endl; for (i=0;i<3;i++) for (j=0;j<3;j++) cout << i << " " << j << " " << band(DDd[i][j]) << endl; cout << flush; } // print d,Dd,DDd. static void output2(interval d,interval Dd[2],interval DDd[2][2]) { int i,j; cout << " ----- \n" << band(d) << endl; for (i=0;i<2;i++) cout << i << " " << band(Dd[i]) << endl; for (i=0;i<2;i++) for (j=0;j<2;j++) cout << i << " " << j << " " << band(DDd[i][j]) << endl; cout << flush; } // static void computeRogersTerm(interval x,interval y,interval z, interval& f,interval Df[2],interval DDf[2][2]) {// the nasty polynomial that shows up: Rogers5d double xxmin[2][2],xxmax[2][2]; double xn=interMath::inf(x), yn=interMath::inf(y), zn=interMath::inf(z), xu=interMath::sup(x), yu=interMath::sup(y), zu=interMath::sup(z); interMath::up(); double xu2=xu*xu, yu2=yu*yu, zu2=zu*zu; double xu3=xu*xu2, yu3=yu*yu2, zu3=zu*zu2; interMath::down(); double xn2=xn*xn, yn2=yn*yn, zn2=zn*zn; double xn3=xn2*xn, yn3=yn2*yn, zn3=zn2*zn; double fmin,fmax; interMath::down(); fmin = //=Rogers5d 2.0*xn2*xn*yn2 + 3.0*(xu*(yu2*(-yu2))) + 8.0*xn2*xn*yn*zn + 12.0*(xu*(yu2*(yu*(-zu)))) + 8.0*xn2*xn*zn2 + 12.0*(xu*(yu2*(-zu2))) + 6.0*xn2*zn3 + 12.0*(xu*(yu*(-zu3))) + 8.0*yn2*zn3 + 3.0*(xu*(zu2*(-zu2))) + 8.0*yn*zn2*zn2 + 2.0*zn2*zn2*zn; interMath::up(); fmax = //=Rogers5d 2.0*xu2*xu*yu2 + 3.0*(xn*(yn2*(-yn2))) + 8.0*xu2*xu*yu*zu + 12.0*(xn*(yn2*(yn*(-zn)))) + 8.0*xu2*xu*zu2 + 12.0*(xn*(yn2*(-zn2))) + 6.0*xu2*zu3 + 12.0*(xn*(yn*(-zn3))) + 8.0*yu2*zu3 + 3.0*(xn*(zn2*(-zn2))) + 8.0*yu*zu2*zu2 + 2.0*zu2*zu2*zu; f = interval(fmin,fmax); // Warning!! We never use the z-derivatives, so we set them to zero. interMath::down(); xxmin[0][0] = 12.0*(xn*yn2 + 4.0*xn*zn*(yn+zn) + zn3); xxmin[0][1]=xxmin[1][0]= 12.0*(xn2*yn -yu3 + 2.0*xn2*zn + 3.0*(yu2*(-zu)) + 2.0*(yu*(-zu2)) - zu3); xxmin[1][1]=4.0*(xn3+9.0*(xu*(-yu2))+18.0*(xu*(yu*(-zu))) + 6.0*(xu*(-zu2)) +4.0*zn3); interMath::up(); xxmax[0][0] = 12.0*(xu*yu2 + 4.0*xu*zu*(yu+zu) + zu3); xxmax[0][1]=xxmax[1][0]= 12.0*(xu2*yu -yn3 + 2.0*xu2*zu + 3.0*(yn2*(-zn)) + 2.0*(yn*(-zn2)) - zn3); xxmax[1][1]=4.0*(xu3+9.0*(xn*(-yn2))+18.0*(xn*(yn*(-zn))) + 6.0*(xn*(-zn2)) +4.0*zu3); int i,j; for (i=0;i<2;i++) for (j=0;j<2;j++) DDf[i][j]=interval(xxmin[i][j],xxmax[i][j]); // now for the first derivatives: double xmin[2],xmax[2]; interMath::down(); xmin[0]= 3.0*(2.0*xn2*yn2 +yu2*(-yu2)+8.0*xn2*yn*zn+4.0*(yu3*(-zu)) +8.0*xn2*zn2 + 4.0*(yu2*(-zu2))+4.0*xn*zn3 + 4.0*(yu*(-zu3)) +zu2*(-zu2)); xmin[1]= 4.0*(xn3*yn + 3.0*(xu*(-yu3))+2.0*xn3*zn +9.0*(xu*(yu2*(-zu))) +6.0*(xu*(yu*(-zu2))) + 3.0*(xu*(-zu3))+4.0*yn*zn3+2.0*zn2*zn2); interMath::up(); xmax[0]= 3.0*(2.0*xu2*yu2 +yn2*(-yn2)+8.0*xu2*yu*zu +4.0*(yn3*(-zn)) +8.0*xu2*zu2 + 4.0*(yn2*(-zn2))+4.0*xu*zu3 + 4.0*(yn*(-zn3)) +(zn2*(-zn2))); xmax[1]= 4.0*(xu3*yu + 3.0*(xn*(-yn3))+2.0*xu3*zu +9.0*(xn*(yn2*(-zn))) +6.0*(xn*(yn*(-zn2))) + 3.0*(xn*(-zn3))+4.0*yu*zu3+2.0*zu2*zu2); for (i=0;i<2;i++) Df[i]=interval(xmin[i],xmax[i]); } // x < y < z : rogers simplex variables. // Warning!!, we don't compute z derivatives, they are not needed (z constant). static void computeQuoin(interval x,interval y,interval z,interval& f, interval Df[2],interval DDf[2][2]) // method two : tangent expansion. { static const interval zero("0"); static const interval one("1"); static const interval two("2"); static const interval three("3"); static const interval four("4"); static const interval six("6"); int i,j; interval x2 = x*x; interval y2 = y*y; interval z2 = z*z; interval DDf1[2][2]; DDf1[0][0] = -six*x; DDf1[0][1] = DDf1[1][0]= zero; DDf1[1][1] = zero; interval Df1[2]; Df1[0]= three*(-x*x+z*z); Df1[1]= zero; interval f1 = (-x+z)*(x*x+x*z-two*z*z); interval unum = z2-y2; interval Dunum[2] = {zero,-two*y}; interval DDunum[2][2]= {{zero,zero}, {zero,-two}}; interval uden = y2-x2; interval Duden[2]= {-two*x,two*y}; interval DDuden[2][2] = {{-two,zero}, {zero,two}}; interval u2, Du2[2], DDu2[2][2]; interval atu,Datu[2],DDatu[2][2]; quotient2(unum,Dunum,DDunum,uden,Duden,DDuden,u2,Du2,DDu2); matan(u2,Du2,DDu2,atu,Datu,DDatu); interval g1,Dg1[2],DDg1[2][2]; product2(atu,Datu,DDatu,f1,Df1,DDf1,g1,Dg1,DDg1); interval d5,Dd5[2],DDd5[2][2]; computeRogersTerm(x,y,z,d5,Dd5,DDd5); interval fh,Dfh[2],DDfh[2][2]; Dfivehalves(u2,Du2,DDu2,fh,Dfh,DDfh); //interval lnum,Dlnum[2],DDlnum[2][2]; // same as uden // interval lden; interval yz = y+z; interval yz2=yz*yz; interval yz3=yz*yz2; lden = yz2*yz2*three; interval ldenf = four*three*yz3; interval Dlden[2] = {zero,ldenf}; interval ldenf2 = interval("36.0")*yz2; interval DDlden[2][2]= {{zero,zero}, {zero,ldenf2}}; interval quo,Dquo[2],DDquo[2][2]; quotient2(uden,Duden,DDuden,lden,Dlden,DDlden,quo,Dquo,DDquo); interval xx,Dxx[2],DDxx[2][2]; product2(quo,Dquo,DDquo,fh,Dfh,DDfh,xx,Dxx,DDxx); interval g2,Dg2[2],DDg2[2][2]; product2(xx,Dxx,DDxx,d5,Dd5,DDd5,g2,Dg2,DDg2); // Term g3. interval fz3 = four*z*z2; interval vnum = (-x+y)*(-y+z); interval Dvnum[2]= {y-z,-two*y+z+x}; interval DDvnum[2][2]= {{zero,one},{one,-two}}; interval vden = (x+y)*(y+z); interval Dvden[2]= {y+z,two*y+z+x}; interval DDvden[2][2] = {{zero,one},{one,two}}; interval v,Dv[2],DDv[2][2]; quotient2(vnum,Dvnum,DDvnum,vden,Dvden,DDvden,v,Dv,DDv); interval mv,Dmv[2],DDmv[2][2]; matan(v,Dv,DDv,mv,Dmv,DDmv); interval g3,Dg3[2],DDg3[2][2]; g3 = mv*fz3; for (i=0;i<2;i++) Dg3[i]=fz3*Dmv[i]; for (i=0;i<2;i++) for (j=0;j<2;j++) DDg3[i][j]=fz3*DDmv[i][j]; // Combine terms. m16 because we consistently left out a factor of -1/6. static interval m16 = -one/interval("6.0"); f = m16*(g1+g2+g3); for (i=0;i<2;i++) Df[i] = m16*(Dg1[i]+Dg2[i]+Dg3[i]); for (i=0;i<2;i++) for (j=i;j<2;j++) DDf[i][j]= m16*(DDg1[i][j]+DDg2[i][j]+DDg3[i][j]); for (i=0;i<2;i++) for (j=0;j1.255); wa = interval("0.20846")/interval(double(numIter),double(numIter)); identifyingString="caseNum 0: 1.255-trunc: rogers var(2 dim'l)"; break; case 1 : // SEAN's CASE 1.258... numIter=4000; c=interval("1.2584085723648189697"); wa = (c-one)/interval(double(numIter),double(numIter)); identifyingString="caseNum 1: dodec-trunc: rogers var(2 dim'l)"; break; case 2 : // 1.385; numIter=10000; c=interval("1.385"); wa = (interval("1.255")-one)/interval(double(numIter),double(numIter)); identifyingString="caseNum 2: 1.385-trunc: rogers var(2 dim'l)"; break; case 3 : // CASE SQRT(2). numIter=10000; c=interval("1.41421356237309504880"); wa = (interval("1.255")-one)/interval(double(numIter),double(numIter)); identifyingString="caseNum 3: sqrt2-trunc: rogers var(2 dim'l)"; break; } interval f,fD[2],fDD[2][2]; /*initialize*/{ int i,j; static const interval maxValue= interval(/*float.h*/DBL_MAX,-DBL_MAX); for (i=0;i<3;i++) for (j=0;j<3;j++) fDD[i][j]=maxValue; for (i=0;i<3;i++) fD[i]=maxValue; f = maxValue; } // MAIN LOOP int count = 0; cout << identifyingString << endl << flush; for (int i=0;iinterMath::sup(c)) bn = interMath::sup(c); interMath::up(); bu= bmin + interMath::sup(wa)*double(j+1); if (bu>interMath::sup(c)) bu = interMath::sup(c); b=interval(bn,bu); } /*update f,fD,fDD*/ { int r; interval q,Dq[2],fDDtemp[2][2]; computeQuoin(a,b,c,q,Dq,fDDtemp); for (r=0;r<2;r++) for (int s=0;s<2;s++) fDD[r][s]=interMath::combine(fDD[r][s],fDDtemp[r][s]); for (r=0;r<2;r++) fD[r]=interMath::combine(fD[r],Dq[r]); f=interMath::combine(f,q); } if (0 == (count++ % 1000000)) { cout << "*" << i << " " << band(fDD[0][0]) << endl << flush; } } } /*output results*/ { cout.precision(20); cout << identifyingString << endl; for (i=0;i<2;i++) for (int j=0;j<2;j++) cout << "DD[" << i << "," << j << "]: " << band(fDD[i][j]) << endl; for (i=0;i<2;i++) cout << "Df[" << i << "]: " << band(fD[i]) << endl; cout << "f: " << band(f) << endl; cout << "*" << endl; cout << count << endl; } } ////////// // Compute second derivatives of quoin in terms of x-variables. // static void computeQuoinXvar(int caseNum) { cout << "*" << flush; static const interval four("4"); interval trunc; // truncation radius. int numIter=200,numIter2; // CHANGEABLE use 200 for 1.255 truncation; // x1 and x2 vary between 4 and 4 + wa*numIter // x3 varies between 4 and 4 + wb*numIter2 interval wa,wb; char* identifyingString; // set trunc,wa,wb,numIter2,indentifyingString. switch (caseNum) { case 0 : // 1.255: trunc="1.255"; numIter2=numIter; wa = (four*trunc*trunc-four)/interval(double(numIter),double(numIter)); wb = wa; identifyingString = "QRTET : 1.255-trunc : simplex var(3 dim'l)"; break; case 1 : // SEAN's trunc="1.2584085723648189697"; numIter2=numIter; wa = (four*trunc*trunc-four)/interval(double(numIter),double(numIter)); wb = wa; identifyingString = "QRT: (sean): simplex var(3 dim'l)"; break; case 2 : // 1.385: trunc="1.385"; numIter2=2*numIter; // max ht with 1.385 trunc is 2.51 and (2.3001 = 2.51^2-4...). wa = interval("2.3001")/interval(double(numIter),double(numIter)); wb = (four*trunc*trunc-four)/interval(double(numIter2),double(numIter2)); identifyingString = "FLAT&QRT: 1.385: simplex var(3 dim'l)"; break; case 3 : // sqrt2: trunc="1.4142135623730950488"; numIter2=2*numIter; wa = interval("2.3001")/interval(double(numIter),double(numIter)); wb = four/interval(double(numIter2),double(numIter2)); identifyingString = "FLAT&QRT: sq: simplex var(3 dim'l)"; break; } int count = 0; int i,j,k; interval fDD[3][3]; for (i=0;i<3;i++) for (j=0;j<3;j++) fDD[i][j]=interval(DBL_MAX,-DBL_MIN); // MAIN LOOP for (i=0;i