UNPKG

trigfills

Version:

Sin, cos, tan, asin, acos and atan filled for cross browser consistency.

257 lines (194 loc) 6.2 kB
require ('../dlib/mutil.js') Fdrandom=require ('../dlib/Fdrandom.js') TRG=require('../trigfills.js') Fdrandom=Fdrandom.hot() var tau=Math.PI*2 ,pi=Math.PI ,hpi=Math.PI*0.5 ,qpi=Math.PI*0.25 ,epi=Math.PI*0.125 ,sq3=1.7320508075688772 //sqrt(3) function modp(a,b){ return a-Math.floor(a/b)*b //removes neg } function tan(x,f3,f15,f315,f2k,f155k){ var inv=1 ,mut=0 ,mut2=0 x=modp(x,pi) if(x>hpi){ inv=-1 ,x=pi-x } if(x>qpi){ mut=1 ,x=hpi-x } if(x>epi){ mut2=2, x=x*0.5 } var c=x*x*x, cc=c*c //funky maclaurin series x= x +c*f3 +c*x*x*f15 +cc*x*f315 +cc*c*f2k +cc*c*x*x*f155k if(mut2){ x= 2*x/(1-x*x) } if(mut){ x=1/x } return inv*x } //tweaked factors give atan some extra accuracy var ff3 =100000000000/300000000002 ,ff5 =100000/500002 ,ff7 =1000/7001 ,ff9 =1000/8995 ,ff11=1000/1102 function atan(x){ var pos=1, mut=0, mut2=0 if(x<0){ pos=0,x=0-x } if(x>1){ x=1/x , mut=1 } if(x>0.26794919){ x=(sq3*x-1)/(sq3+x) mut2=1; } var x2=x*x ,x4=x2*x2 ,x8=x4*x4 x=x- x*x2*ff3 +x4*x*ff5 -x4*x2*x*ff7 +x8*x*ff9 -x8*x2*x*ff11 if(mut2){ x+= hpi*f3 } if(mut) {x = hpi-x } if(pos) return x return -x } //~ var f3=1/3,f6=1/6,f120=1/120,f5k=1/5040,f362k=1/364840 //362880 function sintay(x,f6,f120,f5k,f362k){ //taylor series calculation, last fac is tweaked //if(x>qpi){ return costay(hpi-x) } var c=x*x*x return x-(c*f6)+(c*x*x*f120)-(c*c*x*f5k)+(c*c*c*f362k) } //~ var f24=1/24,f720=1/720,f40k=1/40580 //orig: 40320 function costay(x,f2,f24,f720,f40k){ //if(x>qpi){ return sintay(hpi-x) } var x2=x*x,x4=x2*x2 return 1- x2*f2 + x4*f24 - x2*x4*f720 + x4*x4*f40k } function funcomp(fna,fnb,s,e,d){ var tt=0, mx=0 , ttv=0, mxv=0//, cntt=0, ,st=(e-s)*0.9999999999/(d-1) for(var i=s;i<=e;i=i+st){ var x=fna(i),y=fnb(i) //~ console.log(i.toPrecision(2),x,y,x-y) var uu=Math.abs(x-y) tt+=(x-y)*(x-y) if(uu>mx) mx=uu var uv, ax=Math.abs(x),ay=Math.abs(y) uv=Math.abs(x-y)/(ax+ay+0.0001) ttv+=(uv)*(uv) if(uv>mxv) mxv=uv //~ cnt++ } //~ console.log("tot",tt) //~ console.log("mx",mx) return {t:tt,m:mx,tv:ttv,mv:mxv} } var tal=100000000000, max=tal, talv=tal, maxv=max,ocount=0 ///tan //~ var f15=2/15,f315=17/315,f2k=62/2835,f155k=1382/146555 //~ var fg3=1000000000/2999999887,f15=200000000/1500000678 //~ ,f315=170000/3150457,f2k=6200/282874,f155k=1382/146286 // 5.055947837602811e-16 7.50332374011009e-9 //~ var dz=[1,2,17,62,1382] //~ var tz=[3,15,315,2835,146555] //3.9470683287115024e-17 1.5836425504289764e-9 //3.971392736648054e-17 1.5704270106553508e-9 //~ var dz=[1000000000, 200000000, 170000, 6200, 1382] //~ var tz=[2999999887,1500000678,3150457,282874,146286] //~ var tz=[2999999805,1500001014,3150540,282808,145914] //~ var tz=[2999999850,1500000800,3150500,282840,146100] //~ 100000000/299999985,2000000/15000008,1700/31505,620/28284,1382/146100 //3000000124,1500000729,3150180,283141,146537 ///sintay f6)+(c*x*x*f120)-(c*c*x*f5k)+(c*c*c*f362k) ///var f6=1/6,f120=1/120,f5k=1/5040,f362k=1/364840 //362880 var dz=[1000000000, 100000, 1000, 10] var tz=[6000000000,12000000,5040000,3628800] var tz=[6000000060,12000000,5039650,3628880] var tz=[6000000050,12000000,5039680,3628880] //~ var tz=[(5999939+5999872)/2,(1200468+1200179)/2,(50169+50465)/2,(36343794+36287986)/2] //~ var tz=[5999980,12008,49990,3725300] //~ var tz=[6000067,12008,48140,3792800] //~ var tz=[6000067,12008,48140,3815800] /* legacy: 6000000,12000,50400,362880, rel pres 1.2120775634600997e-11 0.0000019535833883605206 abs pres 1.2120775634600997e-11 0.0000019535833883605206 finals for: 600000006,12000,503965,362888, abs pres 5.529476513638039e-19 1.12773956839618e-10 rel pres 6.685436110560587e-19 1.2070854081385238e-10 0.7071067459175165 0.707106745906841 ' ' 1.0675571537888118e-11 finals for: 6000000049,120000,503968,3628880, abs pres 3.41367765558803e-19 8.568634690675481e-11 rel pres 4.0635741978148263e-19 9.28575773878249e-11 0.7071067459872276 0.707106745906841 ' ' 8.038658627640416e-11 */ var fcomp=funcomp //~ fcomp=funcompx //~ tsn=300000 var tsn tsn=10000000 tsn=1000000 tsn=20000000 //~ tsn=10000 //~ tsn=0 var mage=1000 /* */ var fz=[]; fz[0]=tz[0],fz[1]=tz[1],fz[2]=tz[2],fz[3]=tz[3],fz[4]=tz[4] //~ var df=[0,0,0,0,1,-1,3,-3,9,-9,30,-30] var df=[0,0,0,-1,1,-2,2] var mulla=2,mope=0 var zzsteps=137 while(tsn--){ //~ var ofs=Fdrandom.f48()*0.5 var sc = fcomp( function(x){ return Math.sin(x) } ,function(x){ return sintay(x ,dz[0]/tz[0] ,dz[1]/tz[1] ,dz[2]/tz[2] ,dz[3]/tz[3] //~ ,dz[4]/tz[4] ) } ,0.0000000001, qpi-0.0000000001, zzsteps ) //~ console.log(sc) if((sc.t<=tal&&sc.m<=max&&sc.tv<=talv&&sc.mv<=maxv) &&(sc.t<tal||sc.m<max||sc.tv<talv||sc.mv<maxv) ){ tal=sc.t, max=sc.m,talv=sc.tv, maxv=sc.mv, fz[0]=tz[0] fz[1]=tz[1] fz[2]=tz[2] fz[3]=tz[3] //~ fz[4]=tz[4] //~ if(ocount++%1000===1) { console.log(mulla.toFixed(4),"improved",tal,max) console.log(fz.join(" ")) } //~ mulla*=1.1 } //make test set do{ Fdrandom.mixup(df) mulla=Fdrandom.f48()*mage+0.5 //~ tz[0] = fz[0]+Math.floor(df[0] *mulla) //*mulla //~ tz[1] = fz[1]+Math.floor(df[1] *mulla) //*mulla tz[2] = fz[2]+Math.floor(df[2] *mulla) tz[3] = fz[3]+Math.floor(df[3] *mulla) }while((tz[0]!=fz[0])&&(tz[1]!=fz[1])&&(tz[2]!=fz[2])&&(tz[3]!=fz[3])) //~ tz[4] = fz[4]+Math.floor(df[4] *mulla) } console.log("finals for:") sc = funcomp( function(x){ return Math.sin(x) } ,function(x){ return sintay(x ,dz[0]/fz[0] ,dz[1]/fz[1] ,dz[2]/fz[2] ,dz[3]/fz[3] //~ ,dz[4]/tz[4] ) } ,0.0000001, qpi-0.0000001, zzsteps ) console.log(fz.join(",")) console.log("abs pres",sc.t,sc.m) console.log("rel pres",sc.tv,sc.mv) console.log(sintay(0.78539811350441,dz[0]/fz[0] ,dz[1]/fz[1],dz[2]/fz[2],dz[3]/fz[3])) console.log(Math.sin(0.78539811350441)," ",sintay(0.78539811350441,dz[0]/fz[0] ,dz[1]/fz[1],dz[2]/fz[2],dz[3]/fz[3])-Math.sin(0.78539811350441))