summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2013-02-15 13:38:42 -0500
committerErik Schnetter <schnetter@gmail.com>2013-02-15 13:38:42 -0500
commit57f2eef2f575465d7adbb3e3bdf5ff9d32578151 (patch)
tree98aa3d935093ee267e05eb44155cd2ce5fce7f86
parenta6c17f5b48277ae80e1442d5fe5974c637728488 (diff)
downloadvecmathlib-57f2eef2f575465d7adbb3e3bdf5ff9d32578151.zip
vecmathlib-57f2eef2f575465d7adbb3e3bdf5ff9d32578151.tar.gz
Optimize log()
-rw-r--r--coeffs.out300
-rw-r--r--find-coeffs.m2
-rw-r--r--mathfuncs_log.h60
3 files changed, 179 insertions, 183 deletions
diff --git a/coeffs.out b/coeffs.out
index 64c8b46..2f6302e 100644
--- a/coeffs.out
+++ b/coeffs.out
@@ -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);
OpenPOWER on IntegriCloud