diff options
author | Erik Schnetter <schnetter@gmail.com> | 2013-02-15 13:38:42 -0500 |
---|---|---|
committer | Erik Schnetter <schnetter@gmail.com> | 2013-02-15 13:38:42 -0500 |
commit | 57f2eef2f575465d7adbb3e3bdf5ff9d32578151 (patch) | |
tree | 98aa3d935093ee267e05eb44155cd2ce5fce7f86 | |
parent | a6c17f5b48277ae80e1442d5fe5974c637728488 (diff) | |
download | vecmathlib-57f2eef2f575465d7adbb3e3bdf5ff9d32578151.zip vecmathlib-57f2eef2f575465d7adbb3e3bdf5ff9d32578151.tar.gz |
Optimize log()
-rw-r--r-- | coeffs.out | 300 | ||||
-rw-r--r-- | find-coeffs.m | 2 | ||||
-rw-r--r-- | mathfuncs_log.h | 60 |
3 files changed, 179 insertions, 183 deletions
@@ -518,198 +518,198 @@ (-9.0646997836711835175098792263e-7 + 2.21227885549801306549990154396e-7*Power(x,2))))))\ )))))))))))))))} -{Log[(1 + #1)/(1 - #1)] & , 1, 0.000244837271082114499308511919458, - x*(1.99869348034953208568453547811 + - 0.72012194565351749162311815453*Power(x,2))} -{Log[(1 + #1)/(1 - #1)] & , 2, 2.46320296342914798132452996028e-6, - x*(2.00003761630837605006396552498 + - Power(x,2)*(0.66367387971811341404140489565 + - 0.457183618001805465147522034984*Power(x,2)))} -{Log[(1 + #1)/(1 - #1)] & , 3, 1.56282636081578343710669439533e-7, - x*(1.99999890628479267767366662921 + - Power(x,2)*(0.66680907820259603675618891578 + - Power(x,2)*(0.395112893425894593709307727949 + - 0.345788037618088938910909973312*Power(x,2))))} -{Log[(1 + #1)/(1 - #1)] & , 4, 4.1474852669882468439537574415e-9, - x*(2.00000003194404066806296438624 + - Power(x,2)*(0.66666050603040993131591978064 + - Power(x,2)*(0.400327255520269965349620961636 + - Power(x,2)*(0.27875293930742522006201877131 + - 0.284870694522657865424892074379*Power(x,2)))))} -{Log[(1 + #1)/(1 - #1)] & , 5, 1.11992976829697150667002916785e-10, - x*(1.99999999906473539585097710646 + - Power(x,2)*(0.66666691685445407795604519651 + - Power(x,2)*(0.399981105605717430010308235545 + - Power(x,2)*(0.286318031586339962135359858464 + - Power(x,2)*(0.21300949800291684867594821558 + - 0.246916530690470761535391184428*Power(x,2))))))} -{Log[(1 + #1)/(1 - #1)] & , 6, 3.06127577424236982445366828132e-12, - x*(2.00000000002742308988723236632 + - Power(x,2)*(0.6666666569547315666741393621 + - Power(x,2)*(0.400000985949073329729064782735 + - Power(x,2)*(0.285670565066290993666340854608 + - Power(x,2)*(0.223206077310594967086415788196 + - Power(x,2)*(0.170171762493906587247140967385 + - 0.221357029524974136058141989478*Power(x,2)))))))} -{Log[(1 + #1)/(1 - #1)] & , 7, 8.44395695798874649806729024128e-14, - x*(1.99999999999919515662636317585 + - Power(x,2)*(0.66666666703109795187958365863 + - Power(x,2)*(0.399999952217069298017819213295 + - Power(x,2)*(0.285717078363361753816849439381 + - Power(x,2)*(0.222136378262419625583315376166 + - Power(x,2)*(0.183298576726653294967277532387 + - Power(x,2)*(0.139575043870978072188168050219 + - 0.203266356625572149766138879821*Power(x,2))))))))} -{Log[(1 + #1)/(1 - #1)] & , 8, 2.34538269073622598660009320179e-15, - x*(2.00000000000002363683695357635 + - Power(x,2)*(0.66666666665334866073082762705 + - Power(x,2)*(0.400000002188315138057721108226 + - Power(x,2)*(0.2857141232159377789966318254 + - Power(x,2)*(0.222228717406592838268483404019 + - Power(x,2)*(0.181666855020041235084667333232 + - Power(x,2)*(0.155953385261412203072674191138 + +{Log[2, (1 + #1)/(1 - #1)] & , 1, 0.000353225516814953395614335634743, + x*(2.88350517235737277289752104606 + + 1.03891635982964130224072352333*Power(x,2))} +{Log[2, (1 + #1)/(1 - #1)] & , 2, 3.55365070004223048347195133735e-6, + x*(2.88544435063947749212359038276 + + Power(x,2)*(0.95747901503686061408499610719 + + 0.65957653846687896246124609448*Power(x,2)))} +{Log[2, (1 + #1)/(1 - #1)] & , 3, 2.25468184051947656525068987795e-7, + x*(2.88538850388042106595516956395 + + Power(x,2)*(0.96200215034262628756932169194 + + Power(x,2)*(0.57002741193682764193895550312 + + 0.498866687070343238590910977481*Power(x,2))))} +{Log[2, (1 + #1)/(1 - #1)] & , 4, 5.98355642684398209498469870525e-9, + x*(2.88539012786343587248965772685 + + Power(x,2)*(0.96178780600659929206930296869 + + Power(x,2)*(0.57755014627178237959721643293 + + Power(x,2)*(0.402155483172044562892705980539 + + 0.410981538282433293325329456838*Power(x,2)))))} +{Log[2, (1 + #1)/(1 - #1)] & , 5, 1.61571712286596662252326474006e-10, + x*(2.88539008042862520839507460335 + + Power(x,2)*(0.96179705487065579415603084067 + + Power(x,2)*(0.57705075750665329843626727739 + + Power(x,2)*(0.413069604286702248074050790005 + + Power(x,2)*(0.30730774643105569226192109127 + + 0.356225254340649703388223950385*Power(x,2))))))} +{Log[2, (1 + #1)/(1 - #1)] & , 6, 4.41648737829298884672386656866e-12, + x*(2.88539008181748997050601177965 + + Power(x,2)*(0.96179667991461499871193835609 + + Power(x,2)*(0.57707943877942402481302388885 + + Power(x,2)*(0.412135507549085966662866475478 + + Power(x,2)*(0.32201830083227393349400458432 + + Power(x,2)*(0.245505957849293533467804561697 + + 0.319350688761592041428959057652*Power(x,2)))))))} +{Log[2, (1 + #1)/(1 - #1)] & , 7, 1.2182054828770221697553269685e-13, + x*(2.88539008177676567117601117274 + + Power(x,2)*(0.96179669445173881282808321929 + + Power(x,2)*(0.57707794741938820005328259256 + + Power(x,2)*(0.412202612052105347480086431555 + + Power(x,2)*(0.320475051320227723946459855458 + + Power(x,2)*(0.264443947645547871780098560836 + + Power(x,2)*(0.201364223624519571276587631354 + + 0.293251364683280430617251942017*Power(x,2))))))))} +{Log[2, (1 + #1)/(1 - #1)] & , 8, 3.38367197691196656750692481569e-15, + x*(2.8853900817779609154673045876 + + Power(x,2)*(0.96179669390676178378845169338 + + Power(x,2)*(0.57707801951265676052209143045 + + Power(x,2)*(0.412198348675571683211950320583 + + Power(x,2)*(0.320608268545606348908453769291 + + Power(x,2)*(0.262089870831307776895100836167 + + Power(x,2)*(0.224993175526485341519719865208 + Power(x,2)* - (0.116235854995308475603332568461 + - 0.19004029407429759210845815878*Power(x,2)))))))))} -{Log[(1 + #1)/(1 - #1)] & , 9, 6.55049872715539595929854141611e-17, - x*(1.99999999999999930550413562706 + - Power(x,2)*(0.6666666666671431511287545905 + - Power(x,2)*(0.399999999904175264382265582891 + - Power(x,2)*(0.285714294509349219809755396458 + - Power(x,2)*(0.222221780715086585786972062007 + - Power(x,2)*(0.181831427381185947495951629558 + - Power(x,2)*(0.15359896933017598708632667247 + + (0.167692891575220182736912448504 + + 0.274170189830069394974785418563*Power(x,2)))))))))} +{Log[2, (1 + #1)/(1 - #1)] & , 9, 9.45037202901655672811489051683e-17, + x*(2.88539008177792581277410991327 + + Power(x,2)*(0.96179669392666302667713134701 + + Power(x,2)*(0.57707801621733949207376840932 + + Power(x,2)*(0.412198595799726905825871956187 + + Power(x,2)*(0.320598261015170101859472461613 + + Power(x,2)*(0.262327298560598641020007602127 + + Power(x,2)*(0.221596471338300882039273355617 + Power(x,2)* - (0.136212763801306087484128076492 + + (0.196513478841924000569879320851 + Power(x,2)* - (0.097509429292278293235956018849 + - 0.180173715935115504648176919454*Power(x,2))))))))\ + (0.140676370079882918464564658472 + + 0.259935726478127940817401224248*Power(x,2))))))))\ ))} -{Log[(1 + #1)/(1 - #1)] & , 10, 1.8376858229462566840694776319e-18, - x*(2.00000000000000002041265958451 + - Power(x,2)*(0.66666666666664991338928512269 + - Power(x,2)*(0.400000000004045956015871655565 + - Power(x,2)*(0.285714285265097704005444480179 + - Power(x,2)*(0.222222249814109238532947086348 + - Power(x,2)*(0.181817151135306517458979430024 + - Power(x,2)*(0.153870740006789565996421114892 + +{Log[2, (1 + #1)/(1 - #1)] & , 10, 2.65122022347683496946239613319e-18, + x*(2.88539008177792684416909211592 + + Power(x,2)*(0.96179669392595143503641946327 + + Power(x,2)*(0.57707801636142244362372277801 + + Power(x,2)*(0.412198582463091087244709660671 + + Power(x,2)*(0.320598937782003768835598575789 + + Power(x,2)*(0.262306702291465875807459507029 + + Power(x,2)*(0.221988553545710330516218132954 + Power(x,2)* - (0.132951840638140612860767156829 + + (0.191808961165705218265244169737 + Power(x,2)* - (0.121460441279402629417029363099 + + (0.175230376297979315362084166173 + Power(x,2)* - (0.08185830677307776386474563748 + - 0.172737003710330314852428675176*Power(x,2))))))))\ + (0.118096573237086734771668965194 + + 0.249206818630912017394716382638*Power(x,2))))))))\ )))} -{Log[(1 + #1)/(1 - #1)] & , 11, 5.17443919412421074942207802769e-20, - x*(1.99999999999999999939987284932 + - Power(x,2)*(0.66666666666666724721264553538 + - Power(x,2)*(0.399999999999834256255744091172 + - Power(x,2)*(0.285714285736159505303954301263 + - Power(x,2)*(0.222222220611185193265877682552 + - Power(x,2)*(0.181818254895934079014386596795 + - Power(x,2)*(0.153843997700555374349736922209 + +{Log[2, (1 + #1)/(1 - #1)] & , 11, 7.46513776474486175766651339183e-20, + x*(2.88539008177792681385404889781 + + Power(x,2)*(0.96179669392597644245742117593 + + Power(x,2)*(0.57707801635534624526607350412 + + Power(x,2)*(0.412198583142689611930292042901 + + Power(x,2)*(0.320598895651090069271731207444 + + Power(x,2)*(0.262308294681449587353548498562 + + Power(x,2)*(0.221949972553124328217466806088 + Power(x,2)* - (0.13337585498652657985742501356 + + (0.192420684563387418096836844788 + Power(x,2)* - (0.117083552533038882072551722851 + + (0.168915860609077625098790265156 + Power(x,2)* - (0.11019008097151991159591824237 + + (0.158970683372765107558378144203 + Power(x,2)* - (0.06832457688430761068708308519 + - 0.167125778347090927097458505509*Power(x,2))))))))\ + (0.098571528241827292446004723769 + + 0.241111531626056180329614914293*Power(x,2))))))))\ ))))} -{Log[(1 + #1)/(1 - #1)] & , 12, 6.00201959152765507083845578645e-22, - x*(2.00000000000000000001764718524 + - Power(x,2)*(0.66666666666666664679571742631 + - Power(x,2)*(0.400000000000006618809482817992 + - Power(x,2)*(0.285714285713262186739678687546 + - Power(x,2)*(0.222222222311141976639824887371 + - Power(x,2)*(0.181818177014753356143795899699 + - Power(x,2)*(0.153846324918148459281159128836 + +{Log[2, (1 + #1)/(1 - #1)] & , 12, 8.6590839000153497806679773618e-22, + x*(2.88539008177792681474530886864 + + Power(x,2)*(0.96179669392597557623889652718 + + Power(x,2)*(0.57707801635559491186758732276 + + Power(x,2)*(0.412198583109655763987956815468 + + Power(x,2)*(0.32059889810360929037087867957 + + Power(x,2)*(0.262308182322656379891012953366 + + Power(x,2)*(0.221953330018404941397609580724 + Power(x,2)* - (0.133329182294497146281820520349 + + (0.192353350102051616427965626833 + Power(x,2)* - (0.117716659516442146887948426921 + + (0.169829240914385686508959202192 + Power(x,2)* - (0.104459366915733761431995133732 + + (0.150703010623729750322553413631 + Power(x,2)* - (0.101477552180723767419441554747 + + (0.146401161292681193423265912442 + Power(x,2)* - (0.056277452538711395969131412102 + - 0.162930825436405619597095015452*Power(x,2))))))))\ + (0.081191201691462934922479960273 + + 0.235059493865047764564785212195*Power(x,2))))))))\ )))))} -{Log[(1 + #1)/(1 - #1)] & , 13, 4.13847626324449719258576786991e-23, - x*(1.99999999999999999999948098753 + - Power(x,2)*(0.66666666666666666733964524442 + - Power(x,2)*(0.399999999999999741385995588681 + - Power(x,2)*(0.285714285714332011003209143077 + - Power(x,2)*(0.222222222217541657129259127169 + - Power(x,2)*(0.181818182114612932050400305557 + - Power(x,2)*(0.153846141341451840083217825205 + +{Log[2, (1 + #1)/(1 - #1)] & , 13, 5.9705591818195243630092781536e-23, + x*(2.88539008177792681471910058529 + + Power(x,2)*(0.96179669392597560587751931075 + + Power(x,2)*(0.57707801635558498984282820375 + + Power(x,2)*(0.412198583111199194147574891174 + + Power(x,2)*(0.320598897968572573587362970771 + + Power(x,2)*(0.262308189680198499281563178616 + + Power(x,2)*(0.221953065173215106103005144546 + Power(x,2)* - (0.13333369783235995256565745357 + + (0.192359864646133233402062603701 + Power(x,2)* - (0.117639571011290698115034865942 + + (0.169718025710294148055254697153 + Power(x,2)* - (0.105372166363989028441232421528 + + (0.152019901861053805998416606222 + Power(x,2)* - (0.094123727718059134694550761578 + + (0.135791835208826981756157660033 + Power(x,2)* - (0.094728609033998579173218316682 + + (0.136664494483659208601721894303 + Power(x,2)* - (0.0452819835871539242437599402179 + - 0.159865864524633024873275225981*Power(x,2))))))))\ + (0.065328093162802400644205988938 + + 0.230637689957114926453870012547*Power(x,2))))))))\ ))))))} -{Log[(1 + #1)/(1 - #1)] & , 14, 1.17445849063414605177535114492e-24, - x*(2.0000000000000000000000152664 + - Power(x,2)*(0.66666666666666666664408322064 + - Power(x,2)*(0.400000000000000009915829337126 + - Power(x,2)*(0.285714285714283680432272720053 + - Power(x,2)*(0.222222222222458804441809948775 + - Power(x,2)*(0.181818181800840689939732885915 + - Power(x,2)*(0.153846154699581884336447969892 + +{Log[2, (1 + #1)/(1 - #1)] & , 14, 1.69438544016781953629212102979e-24, + x*(2.88539008177792681471987138677 + + Power(x,2)*(0.96179669392597560487403542841 + + Power(x,2)*(0.57707801635558537724948768337 + + Power(x,2)*(0.412198583111129467872561581412 + + Power(x,2)*(0.32059889797566651763050053488 + + Power(x,2)*(0.26230818922752084161989211968 + + Power(x,2)*(0.22195308444492307649700958038 + Power(x,2)* - (0.133333303997466421258356487577 + + (0.192359296462485406752125833936 + Power(x,2)* - (0.117647779916047701356428015345 + + (0.1697298686564782064528212357 + Power(x,2)* - (0.105250341034962231004288298031 + + (0.151844145063012179049439790657 + Power(x,2)* - (0.095402766636738387048039564642 + + (0.137637098313909521272932631047 + Power(x,2)* - (0.085447651596263039206564587969 + + (0.123274903213536604711294449168 + Power(x,2)* - (0.08954775372597583491372314395 + + (0.129190100223211532469792685441 + Power(x,2)* - (0.0350260928639782639457791362212 + - 0.157725226134361613299983647051*Power(x,2))))))))\ + (0.050531970476577750903029394995 + + 0.227549401567133827549136369236*Power(x,2))))))))\ )))))))} -{Log[(1 + #1)/(1 - #1)] & , 15, 3.33724934581893386882173884498e-26, - x*(1.9999999999999999999999995509 + - Power(x,2)*(0.66666666666666666666741842578 + - Power(x,2)*(0.399999999999999999626024551056 + - Power(x,2)*(0.285714285714285801391639007309 + - Power(x,2)*(0.222222222222210676810175351662 + - Power(x,2)*(0.181818181819150692743997221564 + - Power(x,2)*(0.153846153791214168881901155582 + +{Log[2, (1 + #1)/(1 - #1)] & , 15, 4.81463308142290764951786901939e-26, + x*(2.88539008177792681471984871409 + + Power(x,2)*(0.96179669392597560490770101314 + + Power(x,2)*(0.57707801635558536240443734679 + + Power(x,2)*(0.412198583111132527770121251035 + + Power(x,2)*(0.320598897975308545126833778146 + + Power(x,2)*(0.262308189253936591864267290154 + + Power(x,2)*(0.221953083134425478107097881328 + Power(x,2)* - (0.133333335527674722238682938608 + + (0.192359341950960560772471526618 + Power(x,2)* - (0.117646995448106002495310983897 + + (0.169728736908468981133415194926 + Power(x,2)* - (0.105264501340763111637523909782 + + (0.151864574065968580760414902804 + Power(x,2)* - (0.09521708276418861863351727476 + + (0.13736921311180891205906964422 + Power(x,2)* - (0.08719789704609714772407704527 + + (0.125799973644350746061023620114 + Power(x,2)* - (0.077997279870289942276774132696 + + (0.11252628887169587070384439329 + Power(x,2)* - (0.085665453295335927451616650436 + + (0.123589124644686251190664148348 + Power(x,2)* - (0.0252777762663409318736850266496 + - 0.156357924396727755078629588372*Power(x,2))))))))\ + (0.0364681224641507987586637527353 + + 0.225576802130850598605366685303*Power(x,2))))))))\ ))))))))} {2^#1 & , 1, 0.0377184175144159683187524189042, 1.02014349907778952618207174634 + 0.70151027081131594019995960628*x} diff --git a/find-coeffs.m b/find-coeffs.m index 1fa8ed1..d33e532 100644 --- a/find-coeffs.m +++ b/find-coeffs.m @@ -11,7 +11,7 @@ funcs = {Cos[2 Pi #]&, 0, 1/4, False, 0, 2, 10}, {Tan, 0, Pi/4, False, 1, 2, 20}, (* {Cot, 0, Pi/2, False, 0, 2, 10}, *) - {Log[(1+#)/(1-#)]&, 0, 1/3, False, 1, 2, 15}, + {Log[2, (1+#)/(1-#)]&, 0, 1/3, False, 1, 2, 15}, {2^#&, -1/2, +1/2, False, 0, 1, 15}, {ArcTan, 0, 1, False, 1, 2, 25} }; diff --git a/mathfuncs_log.h b/mathfuncs_log.h index 75eedd2..968bfa0 100644 --- a/mathfuncs_log.h +++ b/mathfuncs_log.h @@ -21,42 +21,38 @@ namespace vecmathlib { x = scalbn(x, -ilogb_x); assert(all(x >= RV(1.0) && x < RV(2.0))); - // Approximate - // for |x|>0.01: (*) log(x) = Sum[n=1,nmax,n%2==1] 2/n ((x-1) / (x+1))^n - // else: (**) log(x) = Sum[n=1,nmax] (-1)^(n+1) 1/n (x-1)^n assert(all(x >= RV(1.0) && x < RV(2.0))); - // nmax max_error of (*) - // 5 5.9e-5 - // 7 1.3e-6 - // 9 2.9e-8 - // 15 4.4e-13 - // 17 1.1e-14 - // 19 3.0e-16 - int const nmax = sizeof(real_t)==4 ? 9 : 17; - x *= RV(M_SQRT1_2); // shift range to increase accuracy + realvec_t y = (x - RV(1.0)) / (x + RV(1.0)); + realvec_t y2 = y*y; - realvec_t xm1 = x - RV(1.0); - boolvec_t near1 = fabs(xm1) < RV(0.0001); // epsilon^(1/niters) - - // for (*) - realvec_t xm1_xp1 = xm1 / (x + RV(1.0)); - realvec_t xm1_xp1_2 = xm1_xp1 * xm1_xp1; - - // for (**) - realvec_t mxm1 = - xm1; - - realvec_t y = ifthen(near1, xm1, RV(2.0) * xm1_xp1); - realvec_t yf = ifthen(near1, mxm1, xm1_xp1_2); - y *= RV(M_LOG2E); - - realvec_t r = y; - for (int n=3, nn=2; n<nmax; n+=2, ++nn) { - y *= yf; - r += y * ifthen(near1, RV(R(1.0) / R(nn)), RV(R(1.0) / R(n))); + realvec_t r; + switch (sizeof(real_t)) { + case 4: + // float, error=5.98355642684398209498469870525e-9 + r = RV(0.410981538282433293325329456838); + r = fma(r, y2, RV(0.402155483172044562892705980539)); + r = fma(r, y2, RV(0.57755014627178237959721643293)); + r = fma(r, y2, RV(0.96178780600659929206930296869)); + r = fma(r, y2, RV(2.88539012786343587248965772685)); + break; + case 8: + // double, error=9.45037202901655672811489051683e-17 + r = RV(0.259935726478127940817401224248); + r = fma(r, y2, RV(0.140676370079882918464564658472)); + r = fma(r, y2, RV(0.196513478841924000569879320851)); + r = fma(r, y2, RV(0.221596471338300882039273355617)); + r = fma(r, y2, RV(0.262327298560598641020007602127)); + r = fma(r, y2, RV(0.320598261015170101859472461613)); + r = fma(r, y2, RV(0.412198595799726905825871956187)); + r = fma(r, y2, RV(0.57707801621733949207376840932)); + r = fma(r, y2, RV(0.96179669392666302667713134701)); + r = fma(r, y2, RV(2.88539008177792581277410991327)); + break; + default: + __builtin_unreachable(); } - - r += RV(0.5); // correct result for range shift + r *= y; // Undo rescaling r += convert_float(ilogb_x); |