test_hp.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. """
  2. Check that the output from irrational functions is accurate for
  3. high-precision input, from 5 to 200 digits. The reference values were
  4. verified with Mathematica.
  5. """
  6. import time
  7. from mpmath import *
  8. precs = [5, 15, 28, 35, 57, 80, 100, 150, 200]
  9. # sqrt(3) + pi/2
  10. a = \
  11. "3.302847134363773912758768033145623809041389953497933538543279275605"\
  12. "841220051904536395163599428307109666700184672047856353516867399774243594"\
  13. "67433521615861420725323528325327484262075464241255915238845599752675"
  14. # e + 1/euler**2
  15. b = \
  16. "5.719681166601007617111261398629939965860873957353320734275716220045750"\
  17. "31474116300529519620938123730851145473473708966080207482581266469342214"\
  18. "824842256999042984813905047895479210702109260221361437411947323431"
  19. # sqrt(a)
  20. sqrt_a = \
  21. "1.817373691447021556327498239690365674922395036495564333152483422755"\
  22. "144321726165582817927383239308173567921345318453306994746434073691275094"\
  23. "484777905906961689902608644112196725896908619756404253109722911487"
  24. # sqrt(a+b*i).real
  25. sqrt_abi_real = \
  26. "2.225720098415113027729407777066107959851146508557282707197601407276"\
  27. "89160998185797504198062911768240808839104987021515555650875977724230130"\
  28. "3584116233925658621288393930286871862273400475179312570274423840384"
  29. # sqrt(a+b*i).imag
  30. sqrt_abi_imag = \
  31. "1.2849057639084690902371581529110949983261182430040898147672052833653668"\
  32. "0629534491275114877090834296831373498336559849050755848611854282001250"\
  33. "1924311019152914021365263161630765255610885489295778894976075186"
  34. # log(a)
  35. log_a = \
  36. "1.194784864491089550288313512105715261520511949410072046160598707069"\
  37. "4336653155025770546309137440687056366757650909754708302115204338077595203"\
  38. "83005773986664564927027147084436553262269459110211221152925732612"
  39. # log(a+b*i).real
  40. log_abi_real = \
  41. "1.8877985921697018111624077550443297276844736840853590212962006811663"\
  42. "04949387789489704203167470111267581371396245317618589339274243008242708"\
  43. "014251531496104028712866224020066439049377679709216784954509456421"
  44. # log(a+b*i).imag
  45. log_abi_imag = \
  46. "1.0471204952840802663567714297078763189256357109769672185219334169734948"\
  47. "4265809854092437285294686651806426649541504240470168212723133326542181"\
  48. "8300136462287639956713914482701017346851009323172531601894918640"
  49. # exp(a)
  50. exp_a = \
  51. "27.18994224087168661137253262213293847994194869430518354305430976149"\
  52. "382792035050358791398632888885200049857986258414049540376323785711941636"\
  53. "100358982497583832083513086941635049329804685212200507288797531143"
  54. # exp(a+b*i).real
  55. exp_abi_real = \
  56. "22.98606617170543596386921087657586890620262522816912505151109385026"\
  57. "40160179326569526152851983847133513990281518417211964710397233157168852"\
  58. "4963130831190142571659948419307628119985383887599493378056639916701"
  59. # exp(a+b*i).imag
  60. exp_abi_imag = \
  61. "-14.523557450291489727214750571590272774669907424478129280902375851196283"\
  62. "3377162379031724734050088565710975758824441845278120105728824497308303"\
  63. "6065619788140201636218705414429933685889542661364184694108251449"
  64. # a**b
  65. pow_a_b = \
  66. "928.7025342285568142947391505837660251004990092821305668257284426997"\
  67. "361966028275685583421197860603126498884545336686124793155581311527995550"\
  68. "580229264427202446131740932666832138634013168125809402143796691154"
  69. # (a**(a+b*i)).real
  70. pow_a_abi_real = \
  71. "44.09156071394489511956058111704382592976814280267142206420038656267"\
  72. "67707916510652790502399193109819563864568986234654864462095231138500505"\
  73. "8197456514795059492120303477512711977915544927440682508821426093455"
  74. # (a**(a+b*i)).imag
  75. pow_a_abi_imag = \
  76. "27.069371511573224750478105146737852141664955461266218367212527612279886"\
  77. "9322304536553254659049205414427707675802193810711302947536332040474573"\
  78. "8166261217563960235014674118610092944307893857862518964990092301"
  79. # ((a+b*i)**(a+b*i)).real
  80. pow_abi_abi_real = \
  81. "-0.15171310677859590091001057734676423076527145052787388589334350524"\
  82. "8084195882019497779202452975350579073716811284169068082670778986235179"\
  83. "0813026562962084477640470612184016755250592698408112493759742219150452"\
  84. # ((a+b*i)**(a+b*i)).imag
  85. pow_abi_abi_imag = \
  86. "1.2697592504953448936553147870155987153192995316950583150964099070426"\
  87. "4736837932577176947632535475040521749162383347758827307504526525647759"\
  88. "97547638617201824468382194146854367480471892602963428122896045019902"
  89. # sin(a)
  90. sin_a = \
  91. "-0.16055653857469062740274792907968048154164433772938156243509084009"\
  92. "38437090841460493108570147191289893388608611542655654723437248152535114"\
  93. "528368009465836614227575701220612124204622383149391870684288862269631"
  94. # sin(1000*a)
  95. sin_1000a = \
  96. "-0.85897040577443833776358106803777589664322997794126153477060795801"\
  97. "09151695416961724733492511852267067419573754315098042850381158563024337"\
  98. "216458577140500488715469780315833217177634490142748614625281171216863"
  99. # sin(a+b*i)
  100. sin_abi_real = \
  101. "-24.4696999681556977743346798696005278716053366404081910969773939630"\
  102. "7149215135459794473448465734589287491880563183624997435193637389884206"\
  103. "02151395451271809790360963144464736839412254746645151672423256977064"
  104. sin_abi_imag = \
  105. "-150.42505378241784671801405965872972765595073690984080160750785565810981"\
  106. "8314482499135443827055399655645954830931316357243750839088113122816583"\
  107. "7169201254329464271121058839499197583056427233866320456505060735"
  108. # cos
  109. cos_a = \
  110. "-0.98702664499035378399332439243967038895709261414476495730788864004"\
  111. "05406821549361039745258003422386169330787395654908532996287293003581554"\
  112. "257037193284199198069707141161341820684198547572456183525659969145501"
  113. cos_1000a = \
  114. "-0.51202523570982001856195696460663971099692261342827540426136215533"\
  115. "52686662667660613179619804463250686852463876088694806607652218586060613"\
  116. "951310588158830695735537073667299449753951774916401887657320950496820"
  117. # tan
  118. tan_a = \
  119. "0.162666873675188117341401059858835168007137819495998960250142156848"\
  120. "639654718809412181543343168174807985559916643549174530459883826451064966"\
  121. "7996119428949951351938178809444268785629011625179962457123195557310"
  122. tan_abi_real = \
  123. "6.822696615947538488826586186310162599974827139564433912601918442911"\
  124. "1026830824380070400102213741875804368044342309515353631134074491271890"\
  125. "467615882710035471686578162073677173148647065131872116479947620E-6"
  126. tan_abi_imag = \
  127. "0.9999795833048243692245661011298447587046967777739649018690797625964167"\
  128. "1446419978852235960862841608081413169601038230073129482874832053357571"\
  129. "62702259309150715669026865777947502665936317953101462202542168429"
  130. def test_hp():
  131. for dps in precs:
  132. mp.dps = dps + 8
  133. aa = mpf(a)
  134. bb = mpf(b)
  135. a1000 = 1000*mpf(a)
  136. abi = mpc(aa, bb)
  137. mp.dps = dps
  138. assert (sqrt(3) + pi/2).ae(aa)
  139. assert (e + 1/euler**2).ae(bb)
  140. assert sqrt(aa).ae(mpf(sqrt_a))
  141. assert sqrt(abi).ae(mpc(sqrt_abi_real, sqrt_abi_imag))
  142. assert log(aa).ae(mpf(log_a))
  143. assert log(abi).ae(mpc(log_abi_real, log_abi_imag))
  144. assert exp(aa).ae(mpf(exp_a))
  145. assert exp(abi).ae(mpc(exp_abi_real, exp_abi_imag))
  146. assert (aa**bb).ae(mpf(pow_a_b))
  147. assert (aa**abi).ae(mpc(pow_a_abi_real, pow_a_abi_imag))
  148. assert (abi**abi).ae(mpc(pow_abi_abi_real, pow_abi_abi_imag))
  149. assert sin(a).ae(mpf(sin_a))
  150. assert sin(a1000).ae(mpf(sin_1000a))
  151. assert sin(abi).ae(mpc(sin_abi_real, sin_abi_imag))
  152. assert cos(a).ae(mpf(cos_a))
  153. assert cos(a1000).ae(mpf(cos_1000a))
  154. assert tan(a).ae(mpf(tan_a))
  155. assert tan(abi).ae(mpc(tan_abi_real, tan_abi_imag))
  156. # check that complex cancellation is avoided so that both
  157. # real and imaginary parts have high relative accuracy.
  158. # abs_eps should be 0, but has to be set to 1e-205 to pass the
  159. # 200-digit case, probably due to slight inaccuracy in the
  160. # precomputed input
  161. assert (tan(abi).real).ae(mpf(tan_abi_real), abs_eps=1e-205)
  162. assert (tan(abi).imag).ae(mpf(tan_abi_imag), abs_eps=1e-205)
  163. mp.dps = 460
  164. assert str(log(3))[-20:] == '02166121184001409826'
  165. mp.dps = 15
  166. # Since str(a) can differ in the last digit from rounded a, and I want
  167. # to compare the last digits of big numbers with the results in Mathematica,
  168. # I made this hack to get the last 20 digits of rounded a
  169. def last_digits(a):
  170. r = repr(a)
  171. s = str(a)
  172. #dps = mp.dps
  173. #mp.dps += 3
  174. m = 10
  175. r = r.replace(s[:-m],'')
  176. r = r.replace("mpf('",'').replace("')",'')
  177. num0 = 0
  178. for c in r:
  179. if c == '0':
  180. num0 += 1
  181. else:
  182. break
  183. b = float(int(r))/10**(len(r) - m)
  184. if b >= 10**m - 0.5: # pragma: no cover
  185. raise NotImplementedError
  186. n = int(round(b))
  187. sn = str(n)
  188. s = s[:-m] + '0'*num0 + sn
  189. return s[-20:]
  190. # values checked with Mathematica
  191. def test_log_hp():
  192. mp.dps = 2000
  193. a = mpf(10)**15000/3
  194. r = log(a)
  195. res = last_digits(r)
  196. # Mathematica N[Log[10^15000/3], 2000]
  197. # ...7443804441768333470331
  198. assert res == '43804441768333470331'
  199. # see issue 145
  200. r = log(mpf(3)/2)
  201. # Mathematica N[Log[3/2], 2000]
  202. # ...69653749808140753263288
  203. res = last_digits(r)
  204. assert res == '53749808140753263288'
  205. mp.dps = 10000
  206. r = log(2)
  207. res = last_digits(r)
  208. # Mathematica N[Log[2], 10000]
  209. # ...695615913401856601359655561
  210. assert res == '13401856601359655561'
  211. r = log(mpf(10)**10/3)
  212. res = last_digits(r)
  213. # Mathematica N[Log[10^10/3], 10000]
  214. # ...587087654020631943060007154
  215. assert res == '54020631943060007154', res
  216. r = log(mpf(10)**100/3)
  217. res = last_digits(r)
  218. # Mathematica N[Log[10^100/3], 10000]
  219. # ,,,59246336539088351652334666
  220. assert res == '36539088351652334666', res
  221. mp.dps += 10
  222. a = 1 - mpf(1)/10**10
  223. mp.dps -= 10
  224. r = log(a)
  225. res = last_digits(r)
  226. # ...3310334360482956137216724048322957404
  227. # 372167240483229574038733026370
  228. # Mathematica N[Log[1 - 10^-10]*10^10, 10000]
  229. # ...60482956137216724048322957404
  230. assert res == '37216724048322957404', res
  231. mp.dps = 10000
  232. mp.dps += 100
  233. a = 1 + mpf(1)/10**100
  234. mp.dps -= 100
  235. r = log(a)
  236. res = last_digits(+r)
  237. # Mathematica N[Log[1 + 10^-100]*10^10, 10030]
  238. # ...3994733877377412241546890854692521568292338268273 10^-91
  239. assert res == '39947338773774122415', res
  240. mp.dps = 15
  241. def test_exp_hp():
  242. mp.dps = 4000
  243. r = exp(mpf(1)/10)
  244. # IntegerPart[N[Exp[1/10] * 10^4000, 4000]]
  245. # ...92167105162069688129
  246. assert int(r * 10**mp.dps) % 10**20 == 92167105162069688129