Natural logarithm
Introduction
editThe natural logarithm of any real number greater than zero is usually denoted by abbreviation
For example, natural logarithm of is:
# python code.
import decimal
dD = Decimal = decimal.Decimal
dgt = decimal.getcontext()
Precision = dgt.prec = 100
ln5 = Decimal(5).ln() ; ln5
Decimal('1.609437912434100374600759333226187639525601354268517721912647891474178987707657764630133878093179611')
The base of the system of natural logarithms is the number which may be calculated as follows:
# python code.
e = Decimal(1).exp() ; e
e ** ln5 # e raised to power ln(5).
Decimal('2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427')
Decimal('5.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
raised to power
When we know from calculus that and that
Therefore
Let Then is taken times.
Calculate
pre = 200
Precision = dgt.prec = pre
lne = ( [ root for root in [e] for p in range (1,pre+1) for root in [root.sqrt()] ][-1] - 1 ) * (1 << pre) ; lne
'1.00000000000000000000000000000000000000000000000000000000000031115076389305708535720320268900621202935.....'
Number of accurate digits in result is about
This calculation of is accurate to places of decimals, not bad for one line of simple python code using high-school math.
If all we want to do is calculate we can stop here. However, this method contains many calculations of .sqrt(),
very time consuming.
While simple and accurate, this method is slow.
This page presents a system for calculating that is much faster than this simple method.
Generally, for close to where:
|
Data Structures
editvalues_of_x0
edit
# python code.
import decimal
dD = Decimal = decimal.Decimal
dgt = decimal.getcontext()
Precision = dgt.prec = 100
length = 8191
base = dD(10) ** (dD(1)/(length-1))
list1 = [ base**p for p in range (0,length) ]
dgt.prec = 30
list2 = [ +v for v in list1 ]
values_of_x0 = tuple(list2)
def print_values_of_x0 (print_all=0) :
'''
This function prints contents of tuple values_of_x0.
Default is to print reduced listing.
'''
lines = []
for p in range (0, len(values_of_x0)) :
lines += [ " '{}', # base ** {}".format(values_of_x0[p], p) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
values_of_x01 = eval(str3)
(values_of_x01 == values_of_x0) or ({}[3])
if print_all : pass
else :
lines[15:len(values_of_x0)-15] = ( [ ' '+('#'*22) ] * 3 )
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
if 1 :
str10 = '''
# Tuple values_of_x0 contains {} values from 1 through 10 both included.
# Values have precision of {}.
# Number of lines printed = {}.'''.lstrip()
str11 = str10.format(
len(values_of_x0),
dgt.prec,
len(lines),
)
print_str = '''
# python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
{}
values_of_x0 = {}
'''
print (print_str.format(
str11,
str3,
))
if (len(lines) > 35) : print (str11)
print_values_of_x0 ()
Tuple # python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
# Tuple values_of_x0 contains 8191 values from 1 through 10 both included.
# Values have precision of 30.
# Number of lines printed = 33.
values_of_x0 = tuple([ dD(v) for v in (
'1', # base ** 0
'1.00028118544621897278573806728', # base ** 1
'1.00056244995769311093431302175', # base ** 2
'1.00084379355665441349981435563', # base ** 3
'1.00112521626534113085090592508', # base ** 4
'1.00140671810599776642860462823', # base ** 5
'1.00168829910087507850455334504', # base ** 6
'1.00196995927223008193978827786', # base ** 7
'1.00225169864232604994400083181', # base ** 8
'1.00253351723343251583529417399', # base ** 9
'1.00281541506782527480043461065', # base ** 10
'1.00309739216778638565559792132', # base ** 11
'1.00337944855560417260761078936', # base ** 12
'1.00366158425357322701568746780', # base ** 13
'1.00394379928399440915366181998', # base ** 14
######################
######################
######################
'9.96071693169670355246242166923', # base ** 8176
'9.96351774033180356752203256087', # base ** 8177
'9.96631933651352941713150174299', # base ** 8178
'9.96912172046332775069436351828', # base ** 8179
'9.97192489240270748518907841861', # base ** 8180
'9.97472885255323982267776904570', # base ** 8181
'9.97753360113655826781987911337', # base ** 8182
'9.98033913837435864539075707594', # base ** 8183
'9.98314546448839911780516572726', # base ** 8184
'9.98595257970050020264571915569', # base ** 8185
'9.98876048423254479019624844046', # base ** 8186
'9.99156917830647816098009747521', # base ** 8187
'9.99437866214430800330335030510', # base ** 8188
'9.99718893596810443080299136420', # base ** 8189
'10.0000000000000000000000000000', # base ** 8190
) ])
|
Dictionary dict4
edit
# python code
dict4 = dict()
for p in range (len(values_of_x0)-2,0,-1) :
x0 = values_of_x0[p]
sign,digits,exp = x0.as_tuple()
dD1 = dD((0,digits[:4],0))
if dD1 in dict4 :
del(dict4[dD1])
break
dict4[dD1] = p
keys4 = sorted([ v for v in dict4 ])
start = int(keys4[0]) ; end = 10000
for key in range (start, end) :
if key in dict4 : pass
else :
v = dict4[key-1]
dict4[key] = v
def print_dict4 (print_all=0) :
'''
This function prints contents of dictionary dict4.
Default is to print reduced listing.
'''
keys4 = sorted([ key for key in dict4 ])
lines = [ ]
for key in keys4 :
v = dict4[key]
lines += [ ' ({}, {}), # dict4[{}] = {}. values_of_x0[{}] = {}'.format(key,v, key, v, v, values_of_x0[v]) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'dict( {} )'.format(str2)
dict41 = eval(str3)
(dict41 == dict4) or ({}[4])
if print_all : pass
else :
lines[15:len(keys4)-15] = ( [ ' '+('#'*22) ] * 3 )
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'dict( {} )'.format(str2)
if 1 :
# An example:
x = dD('9.99456789') ; key = 9994 ; value = dict4[key]
x0 = values_of_x0[value]
str10 = '''
# Let x = {}
# This value of x uses key {}. Value associated with this key is {}.
# Value {} is an index into tuple values_of_x0.
# x0 = values_of_x0[{}] = {}.
# x - x0 {} - {}
# In this case, ratio = ------ = -------------------------------------------- = {}
# x0 {}'''.lstrip()
str11 = str10.format(
x,
key, value,
value,
value,x0,
x,x0,
(x-x0)/x0,
x0,
)
# End of an example.
if 1 :
str20 = '''
# Dictionary dict4 contains {} keys from {} through {} both included.
# Number of lines printed = {}.'''.lstrip()
str21 = str20.format(
len(keys4), keys4[0], keys4[-1],
len(lines),
)
print_str = '''
# python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
{}
dict4 = {}
{}
'''
print (print_str.format(
str21,
str3,
str11,
))
if (len(lines) > 35) : print (str21)
print_dict4 ()
Dictionary # python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
# Dictionary dict4 contains 6494 keys from 3506 through 9999 both included.
# Number of lines printed = 33.
dict4 = dict( (
(3506, 4463), # dict4[3506] = 4463. values_of_x0[4463] = 3.50697641293426289558998224666
(3507, 4464), # dict4[3507] = 4464. values_of_x0[4464] = 3.50796252366181322886561787736
(3508, 4465), # dict4[3508] = 4465. values_of_x0[4465] = 3.50894891166934850969761612419
(3509, 4466), # dict4[3509] = 4466. values_of_x0[4466] = 3.50993557703483583438104568033
(3510, 4467), # dict4[3510] = 4467. values_of_x0[4467] = 3.51092251983626422242373736544
(3511, 4468), # dict4[3511] = 4468. values_of_x0[4468] = 3.51190974015164462271077248878
(3512, 4469), # dict4[3512] = 4469. values_of_x0[4469] = 3.51289723805900991967070457669
(3513, 4470), # dict4[3513] = 4470. values_of_x0[4470] = 3.51388501363641493944351495183
(3514, 4471), # dict4[3514] = 4471. values_of_x0[4471] = 3.51487306696193645605030265189
(3515, 4472), # dict4[3515] = 4472. values_of_x0[4472] = 3.51586139811367319756470917515
(3516, 4473), # dict4[3516] = 4473. values_of_x0[4473] = 3.51685000716974585228607854104
(3517, 4474), # dict4[3517] = 4474. values_of_x0[4474] = 3.51783889420829707491435315329
(3518, 4475), # dict4[3518] = 4475. values_of_x0[4475] = 3.51882805930749149272670595406
(3519, 4476), # dict4[3519] = 4476. values_of_x0[4476] = 3.51981750254551571175590935706
(3520, 4477), # dict4[3520] = 4477. values_of_x0[4477] = 3.52080722400057832297044144817
######################
######################
######################
(9985, 8185), # dict4[9985] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
(9986, 8185), # dict4[9986] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
(9987, 8185), # dict4[9987] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
(9988, 8186), # dict4[9988] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
(9989, 8186), # dict4[9989] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
(9990, 8186), # dict4[9990] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
(9991, 8187), # dict4[9991] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
(9992, 8187), # dict4[9992] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
(9993, 8187), # dict4[9993] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
(9994, 8188), # dict4[9994] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
(9995, 8188), # dict4[9995] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
(9996, 8188), # dict4[9996] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
(9997, 8189), # dict4[9997] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
(9998, 8189), # dict4[9998] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
(9999, 8189), # dict4[9999] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
) )
# Let x = 9.99456789
# This value of x uses key 9994. Value associated with this key is 8188.
# Value 8188 is an index into tuple values_of_x0.
# x0 = values_of_x0[8188] = 9.99437866214430800330335030510.
# x - x0 9.99456789 - 9.99437866214430800330335030510
# In this case, ratio = ------ = -------------------------------------------- = 0.0000189334286891425018292826392422
# x0 9.99437866214430800330335030510
|
Dictionary dict5
edit
# python code.
dict5 = dict()
for p in range (4463,-1,-1) :
x0 = values_of_x0[p]
sign,digits,exp = x0.as_tuple()
dD1 = dD((0,(digits+(0,0,0,0))[:5],0))
if dD1 in dict5 :
del(dict5[dD1])
break
dict5[dD1] = p
keys5 = sorted([ v for v in dict5 ])
start = int(keys5[0]) ; end = keys5[-1]
for key in range (start, 35070) :
if key in dict5 : pass
else :
v = dict5[key-1]
dict5[key] = v
def print_dict5 (print_all=0) :
'''
This function prints contents of dictionary dict5.
Default is to print reduced listing.
'''
keys5 = sorted([ key for key in dict5 ])
lines = [ ]
for key in keys5 :
v = dict5[key]
lines += [ ' ({}, {}), # dict5[{}] = {}. values_of_x0[{}] = {}'.format(key,v, key, v, v, values_of_x0[v]) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'dict( {} )'.format(str2)
dict51 = eval(str3)
(dict51 == dict5) or ({}[5])
if print_all : pass
else :
lines[15:len(keys5)-15] = ( [ ' '+('#'*22) ] * 3 )
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'dict( {} )'.format(str2)
if 1 :
# An example:
x = dD('3.50667891') ; key = 35066 ; value = dict5[key]
x0 = values_of_x0[value]
str10 = '''
# Let x = {}
# This value of x uses key {}. Value associated with this key is {}.
# Value {} is an index into tuple values_of_x0.
# x0 = values_of_x0[{}] = {}.
# x - x0 {} - {}
# In this case, ratio = ------ = -------------------------------------------- = {}
# x0 {}'''.lstrip()
str11 = str10.format(
x,
key, value,
value,
value,x0,
x,x0,
(x-x0)/x0,
x0,
)
# End of an example.
if 1 :
str20 = '''
# Dictionary dict5 contains {} keys from {} through {} both included.
# Number of lines printed = {}.'''.lstrip()
str21 = str20.format(
len(keys5), keys5[0], keys5[-1],
len(lines),
)
print_str = '''
# python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
{}
dict5 = {}
{}
'''
print (print_str.format(
str21,
str3,
str11,
))
if (len(lines) > 35) : print (str21)
print_dict5 ()
Dictionary # python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
# Dictionary dict5 contains 25070 keys from 10000 through 35069 both included.
# Number of lines printed = 33.
dict5 = dict( (
(10000, 0), # dict5[10000] = 0. values_of_x0[0] = 1
(10001, 0), # dict5[10001] = 0. values_of_x0[0] = 1
(10002, 1), # dict5[10002] = 1. values_of_x0[1] = 1.00028118544621897278573806728
(10003, 1), # dict5[10003] = 1. values_of_x0[1] = 1.00028118544621897278573806728
(10004, 1), # dict5[10004] = 1. values_of_x0[1] = 1.00028118544621897278573806728
(10005, 2), # dict5[10005] = 2. values_of_x0[2] = 1.00056244995769311093431302175
(10006, 2), # dict5[10006] = 2. values_of_x0[2] = 1.00056244995769311093431302175
(10007, 2), # dict5[10007] = 2. values_of_x0[2] = 1.00056244995769311093431302175
(10008, 3), # dict5[10008] = 3. values_of_x0[3] = 1.00084379355665441349981435563
(10009, 3), # dict5[10009] = 3. values_of_x0[3] = 1.00084379355665441349981435563
(10010, 3), # dict5[10010] = 3. values_of_x0[3] = 1.00084379355665441349981435563
(10011, 4), # dict5[10011] = 4. values_of_x0[4] = 1.00112521626534113085090592508
(10012, 4), # dict5[10012] = 4. values_of_x0[4] = 1.00112521626534113085090592508
(10013, 4), # dict5[10013] = 4. values_of_x0[4] = 1.00112521626534113085090592508
(10014, 5), # dict5[10014] = 5. values_of_x0[5] = 1.00140671810599776642860462823
######################
######################
######################
(35055, 4461), # dict5[35055] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
(35056, 4461), # dict5[35056] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
(35057, 4461), # dict5[35057] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
(35058, 4461), # dict5[35058] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
(35059, 4462), # dict5[35059] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35060, 4462), # dict5[35060] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35061, 4462), # dict5[35061] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35062, 4462), # dict5[35062] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35063, 4462), # dict5[35063] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35064, 4462), # dict5[35064] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35065, 4462), # dict5[35065] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35066, 4462), # dict5[35066] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35067, 4462), # dict5[35067] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35068, 4462), # dict5[35068] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
(35069, 4463), # dict5[35069] = 4463. values_of_x0[4463] = 3.50697641293426289558998224666
) )
# Let x = 3.50667891
# This value of x uses key 35066. Value associated with this key is 4462.
# Value 4462 is an index into tuple values_of_x0.
# x0 = values_of_x0[4462] = 3.50599057940875233062564717952.
# x - x0 3.50667891 - 3.50599057940875233062564717952
# In this case, ratio = ------ = -------------------------------------------- = 0.000196329846203907638094539889319
# x0 3.50599057940875233062564717952
|
Decision Points
edit
# python code
decision_points=[]
for p in range (0, len(values_of_x0)-1) :
a,b = values_of_x0[p], values_of_x0[p+1]
# ab
# ratio = ---------
# (a + b)/2
decision_point = 2*a*b/(a+b)
decision_points += [ decision_point ]
decision_points = tuple(decision_points)
def print_decision_points(print_all=0) :
'''
This function prints contents of tuple decision_points.
Default is to print reduced listing.
'''
lines = []
for p in range (0, len(decision_points)) :
lines += [ " '{}', # Decision point for values_of_x0[{}], {}".format(decision_points[p], p, values_of_x0[p]) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
decision_points1 = eval(str3)
(decision_points1 == decision_points) or ({}[3])
if print_all : pass
else :
lines[15:len(values_of_x0)-16] = ( [ ' '+('#'*22) ] * 3 )
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
if 1 :
# Check the decision points:
list1 = []
for p in range (0, len(decision_points)) :
x = decision_points[p]
x0 = values_of_x0[p]
list1 += [ (x-x0)/x0 ]
x0 = values_of_x0[p+1]
list1 += [ (x-x0)/x0 ]
list2 = sorted(list1)
str11 = '''
# If x == {}, initial x0 chosen is values_of_x0[8188].
# Ratio (x-x0)/x0 for this value of x0 = {}
# However, x >= decision_points[8188],
# therefore x0 chosen is values_of_x0[8189].
# Ratio (x-x0)/x0 for this value of x0 = {}
# Minimum value of (x-x0)/x0 = {}
# Maximum value of (x-x0)/x0 = {}'''.lstrip()
x = dD('9.996')
str12 = str11.format(
x,
( x - values_of_x0[8188] )/values_of_x0[8188],
( x - values_of_x0[8189] )/values_of_x0[8189],
list2[0],
list2[-1],
)
if 2 :
str20 = '''
# Tuple decision_points contains {} values.
# Values have precision of {}.
# Number of lines printed = {}.'''.lstrip()
str21 = str20.format(
len(decision_points),
dgt.prec,
len(lines),
)
print_str = '''
# python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
{}
decision_points = {}
{}
'''
print (print_str.format(
str21,
str3,
str12,
))
if (len(lines) > 35) : print (str21)
print_decision_points ()
Tuple # python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
# Tuple decision_points contains 8190 values.
# Values have precision of 30.
# Number of lines printed = 33.
decision_points = tuple([ dD(v) for v in (
'1.00014057295957430428168296256', # Decision point for values_of_x0[0], 1
'1.00042179793286364128979317200', # Decision point for values_of_x0[1], 1.00028118544621897278573806728
'1.00070310198252258057883287150', # Decision point for values_of_x0[2], 1.00056244995769311093431302175
'1.00098448513078624642079583976', # Decision point for values_of_x0[3], 1.00084379355665441349981435563
'1.00126594739989601528101601040', # Decision point for values_of_x0[4], 1.00112521626534113085090592508
'1.00154748881209951757619324607', # Decision point for values_of_x0[5], 1.00140671810599776642860462823
'1.00182910938965063943291344401', # Decision point for values_of_x0[6], 1.00168829910087507850455334504
'1.00211080915480952444666311171', # Decision point for values_of_x0[7], 1.00196995927223008193978827786
'1.00239258812984257544133855191', # Decision point for values_of_x0[8], 1.00225169864232604994400083181
'1.00267444633702245622924979608', # Decision point for values_of_x0[9], 1.00253351723343251583529417399
'1.00295638379862809337161942522', # Decision point for values_of_x0[10], 1.00281541506782527480043461065
'1.00323840053694467793957641743', # Decision point for values_of_x0[11], 1.00309739216778638565559792132
'1.00352049657426366727564516130', # Decision point for values_of_x0[12], 1.00337944855560417260761078936
'1.00380267193288278675572977430', # Decision point for values_of_x0[13], 1.00366158425357322701568746780
'1.00408492663510603155159386566', # Decision point for values_of_x0[14], 1.00394379928399440915366181998
######################
######################
######################
'9.95931672423813306357100081673', # Decision point for values_of_x0[8175], 9.95791691038684497262024697178
'9.96211713915527404135384252174', # Decision point for values_of_x0[8176], 9.96071693169670355246242166923
'9.96491834150833309369022259996', # Decision point for values_of_x0[8177], 9.96351774033180356752203256087
'9.96772033151872574057278088598', # Decision point for values_of_x0[8178], 9.96631933651352941713150174299
'9.97052310940792976081594615060', # Decision point for values_of_x0[8179], 9.96912172046332775069436351828
'9.97332667539748520956221068667', # Decision point for values_of_x0[8180], 9.97192489240270748518907841861
'9.97613102970899443579332740474', # Decision point for values_of_x0[8181], 9.97472885255323982267776904570
'9.97893617256412209984643082198', # Decision point for values_of_x0[8182], 9.97753360113655826781987911337
'9.98174210418459519093508332990', # Decision point for values_of_x0[8183], 9.98033913837435864539075707594
'9.98454882479220304467524812459', # Decision point for values_of_x0[8184], 9.98314546448839911780516572726
'9.98735633460879736061619018673', # Decision point for values_of_x0[8185], 9.98595257970050020264571915569
'9.99016463385629221977630669417', # Decision point for values_of_x0[8186], 9.98876048423254479019624844046
'9.99297372275666410218388825624', # Decision point for values_of_x0[8187], 9.99156917830647816098009747521
'9.99578360153195190442281235396', # Decision point for values_of_x0[8188], 9.99437866214430800330335030510
'9.99859427040425695718317037442', # Decision point for values_of_x0[8189], 9.99718893596810443080299136420
) ])
# If x == 9.996, initial x0 chosen is values_of_x0[8188].
# Ratio (x-x0)/x0 for this value of x0 = 0.000162224977710033689939296541400
# However, x >= decision_points[8188],
# therefore x0 chosen is values_of_x0[8189].
# Ratio (x-x0)/x0 for this value of x0 = -0.000118927027959514803376227947800
# Minimum value of (x-x0)/x0 = -0.000140572959574304281682962568892
# Maximum value of (x-x0)/x0 = 0.000140572959574304281682962568536
|
values_of_ln_x0_
edit
# python code
Precision = dgt.prec = 115 # Preparing for values containing 110 places of decimal numbers.
Tolerance = Decimal('1e-' + str( Precision-3 ))
ln_x_Global_Flag = 0
def ln_x (x, x0, C) :
'''
Return ln(x) for x close to x0.
ln_x_ = ln_x (x, x0, C)
C is the constant of integration. Usually C = ln(x0).
If ln_x_Global_Flag is non-zero, this function prints useful information.
'''
global ln_x_Global_Flag
if ln_x_Global_Flag :
thisName = 'ln_x (x, x0, C=0) :'
print (thisName)
print (' x =', x)
print (' x0 =', x0)
print (' C =', C)
status = 1 ; limit = dgt.prec
sum = progressiveValue = multiplier = (x - x0)/x0
progressiveValue *= multiplier
addendum = progressiveValue / 2
sum -= addendum
min,max = sorted((C,abs(progressiveValue)))
limit_small = Tolerance * max
if ln_x_Global_Flag :
print (' multiplier =', multiplier)
print (' limit =', limit)
print()
print (' addendum =', addendum)
print (' sum =', sum)
for p in range (3, limit, 2) :
progressiveValue *= multiplier
addendum = progressiveValue / p
sum += addendum
progressiveValue *= multiplier
addendum = progressiveValue / (p+1)
sum -= addendum
if ln_x_Global_Flag :
print()
print (' addendum =', addendum)
print (' sum =', sum)
if (abs(addendum) < limit_small) :
status = 0
break
if (status) :
print ('ln_x():')
print (' error: count expired, p =',p)
return
output = sum + C
if ln_x_Global_Flag :
print (' p =', p)
print (' output =', output)
return output
values_of_ln_x0_ = [ Decimal(0) ]
for p in range(1, len(values_of_x0),1) :
# Size of list values_of_ln_x0_ increases with every pass through this loop.
x = values_of_x0[p]
x0 = values_of_x0[p-1]
C = values_of_ln_x0_[p-1]
ln = ln_x (x, x0, C)
values_of_ln_x0_ += [ ln ]
Precision = dgt.prec = 110
Tolerance = Decimal('1e-' + str( Precision-3 ))
dC = decimal.Context
values_of_ln_x0_ = tuple([ dC(prec=Precision,rounding=decimal.ROUND_HALF_UP).create_decimal(v) for v in values_of_ln_x0_])
def print_values_of_ln_x0_ (print_all=0) :
'''
This function prints contents of tuple values_of_ln_x0_.
Default is to print reduced listing.
'''
lines = []
for p in range (0, len(values_of_ln_x0_)) :
x = values_of_x0[p] ; logn_x_ = values_of_ln_x0_[p]
(logn_x_ == x.ln()) or ({}[17])
lines += [ " '{}', # ln(x) for x = values_of_x0[{}] = {}.".format(logn_x_, p, x) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
values_of_ln_x0_1 = eval(str3)
(values_of_ln_x0_1 == values_of_ln_x0_) or ({}[3])
if print_all : pass
else :
lines[15:len(values_of_ln_x0_)-15] = ( [ ' '+('#'*22) ] * 3 )
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
if 1 :
str20 = '''
# Tuple values_of_ln_x0_ contains {} values.
# Values have precision of {}.
# Number of lines printed = {}.'''.lstrip()
str21 = str20.format(
len(values_of_ln_x0_),
dgt.prec,
len(lines),
)
print_str = '''
# python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
{}
values_of_ln_x0_ = {}
# All values match corresponding values calculated from python's method .ln().
'''
print (print_str.format(
str21,
str3,
))
if (len(lines) > 35) : print (str21)
print_values_of_ln_x0_ ()
Tuple # python code
import decimal
dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
# Tuple values_of_ln_x0_ contains 8191 values.
# Values have precision of 110.
# Number of lines printed = 33.
values_of_ln_x0_ = tuple([ dD(v) for v in (
'0', # ln(x) for x = values_of_x0[0] = 1.
'0.00028114592100049397851257526958789318557823685315140509591146945610630681924483554634842715913155791553935763353', # ln(x) for x = values_of_x0[1] = 1.00028118544621897278573806728.
'0.00056229184200098795702515053832076377529815817685091034900099838032371576474647395210890353807586706979025309841', # ln(x) for x = values_of_x0[2] = 1.00056244995769311093431302175.
'0.00084343776300148193553772580559921306036271356639510059614615649527672916175199470705511306484712247456495136785', # ln(x) for x = values_of_x0[3] = 1.00084379355665441349981435563.
'0.0011245836840019759140503010760592633243233373666630274912240526872189379027309580785200788485985603865985895688', # ln(x) for x = values_of_x0[4] = 1.00112521626534113085090592508.
'0.0014057296050024698925628763418989224560236605191226558916675419561961081724994394224778473772989675950066240433', # ln(x) for x = values_of_x0[5] = 1.00140671810599776642860462823.
'0.0016868755260029638710754516132125138240706054425728603309033120607959071382243819085331207823151560952524126555', # ln(x) for x = values_of_x0[6] = 1.00168829910087507850455334504.
'0.0019680214470034578495880268872333649791972073653457158404410113008355450069732509641759673340415353071544323205', # ln(x) for x = values_of_x0[7] = 1.00196995927223008193978827786.
'0.0022491673680039518281006021580778932979673021988265352275636839430354663150269526071071437607450560006442621246', # ln(x) for x = values_of_x0[8] = 1.00225169864232604994400083181.
'0.0025303132890044458066131774196426391914772962305290824563142073882759834795702976123051014571348552310189175327', # ln(x) for x = values_of_x0[9] = 1.00253351723343251583529417399.
'0.0028114592100049397851257526950841486394900305702168719174622980317602779030546368107920305020685647504214850020', # ln(x) for x = values_of_x0[10] = 1.00281541506782527480043461065.
'0.0030926051310054337636383279576467230904015964551099672846920959011633015793790942523210207705866150801840718264', # ln(x) for x = values_of_x0[11] = 1.00309739216778638565559792132.
'0.0033737510520059277421509032273666711656003353833161378685286907465997110550477881401427392163316523076635049655', # ln(x) for x = values_of_x0[12] = 1.00337944855560417260761078936.
'0.0036548969730064217206634785007033901080823462730164946725801425392961788141621195388687950276169252526202813317', # ln(x) for x = values_of_x0[13] = 1.00366158425357322701568746780.
'0.0039360428940069156991760537694132046752291888691499866508887763250737472392296047255077029503512257389803956675', # ln(x) for x = values_of_x0[14] = 1.00394379928399440915366181998.
######################
######################
######################
'2.2986490501000387683188154009156080387928397456918301259039789087944336216064685316414378199045428924326799354', # ln(x) for x = values_of_x0[8176] = 9.96071693169670355246242166923.
'2.2989301960210392622973279761851826912850498262636764478593466003783569959365230606881295712717359785963112572', # ln(x) for x = values_of_x0[8177] = 9.96351774033180356752203256087.
'2.2992113419420397562758405514538127154368379767714938128234341386785761356659428151509538766438052956987514456', # ln(x) for x = values_of_x0[8178] = 9.96631933651352941713150174299.
'2.2994924878630402502543531267234795446120177448761439909215905629390155692208202036169724706742616903146745976', # ln(x) for x = values_of_x0[8179] = 9.96912172046332775069436351828.
'2.2997736337840407442328657019924935957228985155357974105355104395265542601189816673651603550100698554337262110', # ln(x) for x = values_of_x0[8180] = 9.97192489240270748518907841861.
'2.3000547797050412382113782772620075034105144024446410997113100105048869297857113614199956326399453812234259798', # ln(x) for x = values_of_x0[8181] = 9.97472885255323982267776904570.
'2.3003359256260417321898908525304842706062415677704389700357254056059757438662458766613085787045702337983018714', # ln(x) for x = values_of_x0[8182] = 9.97753360113655826781987911337.
'2.3006170715470422261684034277999240939447294182933534442617229885402608324814372163790494646489096111864238087', # ln(x) for x = values_of_x0[8183] = 9.98033913837435864539075707594.
'2.3008982174680427201469160030695937857213769448822598470814633753680217668218642029270879455834911773531417718', # ln(x) for x = values_of_x0[8184] = 9.98314546448839911780516572726.
'2.3011793633890432141254285783381842630937332590762005140545211954364744522739221910731492477352251364727532941', # ln(x) for x = values_of_x0[8185] = 9.98595257970050020264571915569.
'2.3014605093100437081039411536072957843624648926396223086157833390784873434028789437068207364140323800128952846', # ln(x) for x = values_of_x0[8186] = 9.98876048423254479019624844046.
'2.3017416552310442020824537288772066438368127181180454803304105302438376670970053383184297088473645195882839920', # ln(x) for x = values_of_x0[8187] = 9.99156917830647816098009747521.
'2.3020228011520446960609663041459434200397763370975986092768268975848700083257305096479892286265624964942134938', # ln(x) for x = values_of_x0[8188] = 9.99437866214430800330335030510.
'2.3023039470730451900394788794156639713397781053105254292750160375440587140647147489289589658979929574060205262', # ln(x) for x = values_of_x0[8189] = 9.99718893596810443080299136420.
'2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840', # ln(x) for x = values_of_x0[8190] = 10.0000000000000000000000000000.
) ])
# All values match corresponding values calculated from python's method .ln().
|
nat_logs_of_10_integers
edit
This data structure is included because this author believes that it would be handy to have natural logarithms of the small integers readily available. def simple_ln (x, flag = 0) :
'''
This function calculates ln(x) using the slow, simple method.
Result is accurate to precision as in dgt.prec.
If flag, this function also calculates x.ln() for internal checking.
'''
x_ = dD(str(x))
old_precision = dgt.prec
pre = precision = dgt.prec = int((dgt.prec + 5)*10/3)
lnx = ([ root for root in [x_] for p in range (1,pre+1) for root in [root.sqrt()] ][-1] - 1) * (1 << pre)
dgt.prec = old_precision
lnx += 0
if flag : (x_.ln() == lnx) or ({}[13])
return lnx
# python code
nat_logs_of_10_integers = [0,dD(0)]
for x in range(2,11) :
nlog = simple_ln (x)
nat_logs_of_10_integers += [ nlog ]
nat_logs_of_10_integers = tuple(nat_logs_of_10_integers)
def print_nat_logs_of_10_integers() :
'''
This function prints contents of tuple nat_logs_of_10_integers.
'''
lines = []
lines += [ " '0', # Filler." ]
for x in range (1, len(nat_logs_of_10_integers)) :
logn_x_ = nat_logs_of_10_integers[x]
( logn_x_ == dD(x).ln() ) or ({}[30])
lines += [ " '{}', # ln({}) = nat_logs_of_10_integers[{}]".format(logn_x_, x, x) ]
new_line = '''
'''[-1:]
str1 = new_line.join(lines)
str2 = '({}{}{})'.format(new_line,str1,new_line)
str3 = 'tuple([ dD(v) for v in {} ])'.format(str2)
nat_logs_of_10_integers1 = eval(str3)
(nat_logs_of_10_integers1 == nat_logs_of_10_integers) or ({}[3])
print_str = '''
import decimal
dD = decimal.Decimal
# Tuple nat_logs_of_10_integers contains {} values:
# 1 filler and ln(x) for x in (1,2,3,4,5,6,7,8,9,10).
# Values have precision of {}.
# Number of lines printed = {}.
# All values match corresponding values calculated from python's method .ln().
nat_logs_of_10_integers = {}
'''
print (print_str.format(
len(nat_logs_of_10_integers),
dgt.prec,
len(lines),
str3,
))
print_nat_logs_of_10_integers()
Tuple import decimal
dD = decimal.Decimal
# Tuple nat_logs_of_10_integers contains 11 values:
# 1 filler and ln(x) for x in (1,2,3,4,5,6,7,8,9,10).
# Values have precision of 110.
# Number of lines printed = 11.
# All values match corresponding values calculated from python's method .ln().
nat_logs_of_10_integers = tuple([ dD(v) for v in (
'0', # Filler.
'0', # ln(1) = nat_logs_of_10_integers[1]
'0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102', # ln(2) = nat_logs_of_10_integers[2]
'1.0986122886681096913952452369225257046474905578227494517346943336374942932186089668736157548137320887879700291', # ln(3) = nat_logs_of_10_integers[3]
'1.3862943611198906188344642429163531361510002687205105082413600189867872439393894312117266539928373750840029620', # ln(4) = nat_logs_of_10_integers[4]
'1.6094379124341003746007593332261876395256013542685177219126478914741789877076577646301338780931796107999663030', # ln(5) = nat_logs_of_10_integers[5]
'1.7917594692280550008124773583807022727229906921830047058553743431308879151883036824794790818101507763299715101', # ln(6) = nat_logs_of_10_integers[6]
'1.9459101490553133051053527434431797296370847295818611884593901499375798627520692677876584985878715269930616942', # ln(7) = nat_logs_of_10_integers[7]
'2.0794415416798359282516963643745297042265004030807657623620400284801808659090841468175899809892560626260044431', # ln(8) = nat_logs_of_10_integers[8]
'2.1972245773362193827904904738450514092949811156454989034693886672749885864372179337472315096274641775759400581', # ln(9) = nat_logs_of_10_integers[9]
'2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840', # ln(10) = nat_logs_of_10_integers[10]
) ])
|
Accessing the data structures
editFunction natural_log()
edit
# python code.
natural_log_Global_Flag = 0
def natural_log (x) :
'''
This function calculates x0 and ln(x0), and invokes function ln_x().
ln_x_ = natural_log (x)
x is limited to (10 >= x >= 1).
'''
(10 >= x >= 1) or ({}[89])
if x == 1 : return dD(0)
if x == 10 : return values_of_ln_x0_[-1]
while 1 :
'''
This code is written for speed.
If x == 5.67 key generated is 5670. p = dict4[5670].
If x == 2.3456789 key generated is 23456. p = dict5[23456].
Check values_of_x0[p], values_of_x0[p-1]. Return appropriate value of p.
Result must be found with max of 2 tests. Anything else means internal error.
'''
if x > dD('3.506') :
p = dict4[ int(x * 1_000) ]
if x >= values_of_x0[p] : break
p -= 1
if x >= values_of_x0[p] : break
({}[13])
p = dict5[ int(x * 10_000) ]
if x >= values_of_x0[p] : break
p -= 1
if x >= values_of_x0[p] : break
({}[14])
if x >= decision_points[p] : p += 1
x0 = values_of_x0[p]
C = values_of_ln_x0_[p]
if natural_log_Global_Flag :
print ('natural_log (x) :')
print (' x =', x)
print (' x0 =', x0)
print (' C =', C)
print (' multiplier =', (x-x0)/x0)
if x == x0 : return C
ln_x_ = ln_x (x, x0, C)
if natural_log_Global_Flag :
print (' ln(x) =', ln_x_)
return ln_x_
|
Testing Function natural_log()
editFor accuracy
edit
This test compares # python code.
count = count1 = count2 = count3 = 0
for X in range(100_000_001, 1_000_000_000,101) : # 8910892
count += 1
x = dD(X)/100_000_000
lnx = natural_log (x) ; lnx_ = x.ln()
# test 1
if lnx == lnx_ :
# Both values are equal.
count1 += 1 ; continue
# test 2
str1 = str(lnx).upper() ; str2 = str(lnx_)
if 'E' not in str1 :
if str1[:-1] == str2[:-1] :
# Both values are equal except for least significant digit.
count2 += 1 ; continue
# test 3
v1 = dC(prec=dgt.prec-1,rounding=decimal.ROUND_HALF_UP).create_decimal(lnx)
v2 = dC(prec=dgt.prec-1,rounding=decimal.ROUND_HALF_UP).create_decimal(lnx_)
if v1 == v2 :
# With precision reduced by 1, both values are equal.
count3 += 1 ; continue
({}[17])
values = count1,count2,count3,count
len1 = sorted([ len(str(v)) for v in values ])[-1]
a,b,c,d = [ ((' '*len1)+str(v))[-len1:] for v in values ]
str20 = 'count == count1+count2+count3'
str1 = '''
count1 = {} Both values equal.
count2 = {} Both values equal except for least significant digit.
count3 = {} Both values equal with precision reduced by 1.
count = {}
{}: {}'''.format(a,b,c,d,str20, eval(str20))
print (str1)
count1 = 6687475 Both values equal.
count2 = 2001406 Both values equal except for least significant digit.
count3 = 222011 Both values equal with precision reduced by 1.
count = 8910892
count == count1+count2+count3: True Considering that function |
For speed
edit
# python code.
count = 0
for X in range(100_000_001, 1_000_000_000, 1001) : # 899101
count += 1
x = dD(X)/100_000_000
if 1 : natural_log (x)
else : x.ln()
sx = 'count' ; print (sx, '=', eval(sx))
python3 ./wiki_005.py > j1q 2> j2q 16.85s user 0.02s system 99% cpu 16.878 total
count = 899101 # python code.
count = 0
for X in range(100_000_001, 1_000_000_000, 1001) : # 899101
count += 1
x = dD(X)/100_000_000
if 0 : natural_log (x)
else : x.ln()
sx = 'count' ; print (sx, '=', eval(sx))
python3 ./wiki_005.py > j1q 2> j2q 77.01s user 0.10s system 99% cpu 1:17.11 total
count = 899101 This test indicates that this implementation of |
Putting all together
edit
# python code.
def make_Decimal_number_clean(number) :
'''
Number such as 0.9999999999999999999999999999999999999999
is returned as 1.
Number 0.9999999999999999999999999999999999999999 is described as "raw."
Number 1 is described as "clean."
Number 1E-103 becomes 0.
'''
if abs(number) < Tolerance : return dD(0)
dgt.prec -= 2
dD1 = (+number).normalize()
dgt.prec += 2
sign,digits,exponent = dD1.as_tuple()
if len(digits) < (dgt.prec - (dgt.prec >> 2)) : return dD1
return number
# python code.
def sum_zero(values) :
'''
This function calculates sum of all values.
However, if sum is close to zero and Tolerance permits, sum
is returned as zero.
Useful for testing 2 numbers for being "almost" equal.
For example:
let v1 be 1.9999999999999999999999999999999999999
let v2 be 2
sum_zero((v1,-v2)) returns 0.
'''
sump = sumn = 0
for v in values :
if v > 0 : sump += v
else : sumn -= v
sum = sump - sumn
if abs(sum) < Tolerance : return dD(0)
min,max = sorted((sump,sumn))
if abs(sum) <= Tolerance*min : return dD(0)
return sum
# python code.
import sys
def natural_logarithm (number, flag=0) :
'''
ln_x_ = natural_logarithm (x [,flag])
ln(number) = ln(standard_number * (10 ** exponent))
= ln(standard_number) + ln(10 ** exponent))
= ln(standard_number) + exponent*ln(10)
For example:
ln(12345.6789)
= ln(1.23456789 * 10**4)
= ln(1.23456789) + 4(ln(10))
Value 1.23456789 is called standard_number and 4 is exponent.
print_ = flag & 1
print_all = flag & 2
check = flag & 4
do_not_clean = flag & 8
'''
thisName = 'natural_logarithm (number) :'
error = ''
try :
number = dD(str(number)).normalize()
print_ = flag & 1
except : v1,v2,v3 = error = sys.exc_info()
if error :
print ()
print (thisName)
print (' Input not recognized.')
print (' ', v1)
print (' ', v2)
print (' ', v3)
print ()
return
print_all = flag & 2
check = flag & 4
if print_all : print_ = 1
if print_ : check = 4
do_not_clean = flag & 8
if number <= 0 :
print()
print (thisName)
print (' Input number must be > 0.')
print ()
return
if print_ :
print()
print(thisName)
print(' Input number =', number)
if print_all :
print(' flag =', bin(flag))
if 10 >= number >= 1 :
ln_x_ = natural_log (number)
else :
sign, digits, exponent = number.as_tuple()
if print_all :
print(thisName)
print(' digits =', digits)
print(' exponent =', exponent)
if (len(digits) == 1) :
standard_number = dD(digits[0])
else :
digits = list(digits)
exponent += (len(digits)-1)
digits[1:1] = '.'
standard_number = dD( ''.join([str(v) for v in digits]) )
if standard_number == 1 : standard_log = 0
else : standard_log = natural_log (standard_number)
ln_x_ = standard_log + exponent * nat_logs_of_10_integers[10]
if print_all :
print(thisName)
print(' standard_number =', standard_number)
print(' ln of standard_number =', standard_log)
if check:
# Some internal checking.
b = number ; lnb = ln_x_ ; count = 0
if 1 :
# Two values in each of the following tuples should be equal.
b__2 = ( natural_logarithm(b**2), 2*lnb )
b_2 = ( natural_logarithm(b*2), (lnb + nat_logs_of_10_integers[2]) )
b_5 = ( natural_logarithm(b/5), (lnb - nat_logs_of_10_integers[5]) )
b_r = ( natural_logarithm(1/b), -lnb )
for str1 in 'b__2 b_2 b_5 b_r'.split() :
v1,v2 = eval(str1)
sum = sum_zero((v1,-v2))
if sum :
count += 1
if not print_ :
print_ = 1 ; print()
print (thisName)
if count == 1:
print (' number =', b)
print (' ln_x_ =', ln_x_)
print (' precision =', dgt.prec)
print (' Tolerance =', Tolerance)
print (' Test {} failed.'.format(str1))
print (' v1 =', v1)
print (' v2 =', v2)
print (' sum =', sum)
if count :
print (' Number of errors detected =', count)
print() ; return
if do_not_clean : pass
else : ln_x_ = make_Decimal_number_clean(ln_x_)
if print_ :
print(thisName)
if int(ln_x_) == ln_x_ : print(' Output =', int(ln_x_))
else : print(' Output =', ln_x_ )
print()
return ln_x_
|