Jump to content

Taylor's series

From Wikiversity

A well-behaved function can be expanded into a power series. This means that for all non-negative integers there are real numbers such that

Let us calculate the first four derivatives using :

Setting equal to zero, we obtain

Let us write for the -th derivative of  We also write — think of as the "zeroth derivative" of  We thus arrive at the general result where the factorial  is defined as equal to 1 for and and as the product of all natural numbers for Expressing the coefficients in terms of the derivatives of at we obtain

This is the Taylor series for 

A remarkable result: if you know the value of a well-behaved function and the values of all of its derivatives at the single point then you know at all points  Besides, there is nothing special about so is also determined by its value and the values of its derivatives at any other point :

Examples

[edit | edit source]

cos(x)

[edit | edit source]



Some basic checking:

arctan(x)

[edit | edit source]

. See .

Second derivative y″

[edit | edit source]

Third derivative y¹¹¹

[edit | edit source]

(continued)

[edit | edit source]

If you continue to calculate derivatives, you will produce the following sequence:


Some basic checking:

Also,

Show that

or that

If abs

Figure 1: Graph of Taylor series representing for close to

In the diagram to the right, is the Taylor series representing for close to

In the box above the proof that is an accurate representation of is valid for abs

When abs the diagram vividly illustrates that the series rapidly diverges.

To be accurate, the line should be rad or meaning radians. In theoretical work a value such as is understood to be radians or meaning degrees.

In practice

[edit | edit source]

The expansion of above is theoretically valid for However, if is close to the calculation of will take forever.

This section uses so that is small enough to make time of calculation acceptable.


Let To calculate

Using the half-angle formula

calculate and


This value was chosen for because is close to For approx.

If the code below is accurate to places of decimals.


This section uses the whole sequence of derivatives:

where

where

where

where and so on.


Using

then and:

Figure 1: Graph of Taylor series representing for close to
close to
rad.
y = 0.6414085001079161195194563572
+(0.6420076723519613087221948458)(x-(0.7467354177837216717375001402))
+(-0.3077848130939266477182675970)(x-0.7467354177837216717375001402)^2
+(0.05934881813852229894809158807)(x-0.7467354177837216717375001402)^3
+(0.05612149216561873709345633871)(x-0.7467354177837216717375001402)^4
+(-0.0659097533448882821311588572)(x-0.7467354177837216717375001402)^5
+(0.02864269115336634046783964776)(x-0.7467354177837216717375001402)^6
+(0.006684824489389227404750195292)(x-0.7467354177837216717375001402)^7
+(-0.01939996954693863883077829889)(x-0.7467354177837216717375001402)^8
+(0.01319629210955273736079467214)(x-0.7467354177837216717375001402)^9
+(-0.001423635337528918097834676738)(x-0.7467354177837216717375001402)^10
+(-0.005690817314508170664127596721)(x-0.7467354177837216717375001402)^11
+(0.005763416294060825609852171147)(x-0.7467354177837216717375001402)^12
+(-0.002009530403041012685757678258)(x-0.7467354177837216717375001402)^13
+(-0.001382413103546475118963526286)(x-0.7467354177837216717375001402)^14
+(0.002355235379425975362106687309)(x-0.7467354177837216717375001402)^15
+(-0.001340525935442931206538139095)(x-0.7467354177837216717375001402)^16
+(-0.0001244720120416846251034920203)(x-0.7467354177837216717375001402)^17
+(0.0008777184853106580549638629701)(x-0.7467354177837216717375001402)^18
+(-0.0007257802485492202930793702930)(x-0.7467354177837216717375001402)^19
+(0.0001539460026510816727324277808)(x-0.7467354177837216717375001402)^20
+(0.0002810020934892180446689969911)(x-0.7467354177837216717375001402)^21
+(-0.0003470330774958963760466009045)(x-0.7467354177837216717375001402)^22
+(0.0001535570475871531716152621841)(x-0.7467354177837216717375001402)^23
+(0.00006313260945054237374661397478)(x-0.7467354177837216717375001402)^24
+(-0.0001488094986598041280906554962)(x-0.7467354177837216717375001402)^25
+(0.00009977993191704606200503722720)(x-0.7467354177837216717375001402)^26
+(-0.000003667561779685224841381874106)(x-0.7467354177837216717375001402)^27
+(-0.00005609286432922550484209657985)(x-0.7467354177837216717375001402)^28
+(0.00005412057738460028511566507574)(x-0.7467354177837216717375001402)^29
+(-0.00001655090242419904039018979491)(x-0.7467354177837216717375001402)^30
+(-0.00001714674178231985986067601799)(x-0.7467354177837216717375001402)^31
+(0.00002588855802866968641107644970)(x-0.7467354177837216717375001402)^32
+(-0.00001372909690493026279553133838)(x-0.7467354177837216717375001402)^33
+(-0.000002866406864208033772447118585)(x-0.7467354177837216717375001402)^34
+(0.00001098036048658105543109288040)(x-0.7467354177837216717375001402)^35
+(-0.000008497717911244361532280438636)(x-0.7467354177837216717375001402)^36
+(0.000001259146436001274560243296183)(x-0.7467354177837216717375001402)^37
+(0.000003992939704019955177003526706)(x-0.7467354177837216717375001402)^38
+(-0.000004497268683100848779169934291)(x-0.7467354177837216717375001402)^39
+(0.000001768945188244137235636524921)(x-0.7467354177837216717375001402)^40
+(0.000001091706749083768850937760502)(x-0.7467354177837216717375001402)^41
+(-0.000002103423912310375893571195410)(x-0.7467354177837216717375001402)^42
+(0.000001301617082996039555612971998)(x-0.7467354177837216717375001402)^43
+(6.937967909808721515382339295E-8)(x-0.7467354177837216717375001402)^44
+(-8.635525611989332402947366709E-7)(x-0.7467354177837216717375001402)^45
+(7.673857631132879175874596987E-7)(x-0.7467354177837216717375001402)^46
+(-1.893140553441536683377149770E-7)(x-0.7467354177837216717375001402)^47
+(-2.944033068289732156296704644E-7)(x-0.7467354177837216717375001402)^48
+(3.930991061512879804635643270E-7)(x-0.7467354177837216717375001402)^49
+(-1.879241426421737899718180888E-7)(x-0.7467354177837216717375001402)^50

A faster version
[edit | edit source]

The calculation of above is suitable as input to application grapher.

The following python code has precision set to If it is desired to calculate for one value of the following python code is much faster than the code supplied to grapher above.

python code
[edit | edit source]
data = '''
0.641408500107916119519456357419567
0.642007672351961308722194845349589
-0.307784813093926647718267596858344
0.0593488181385222989480915882567083
0.0561214921656187370934563384765525
-0.0659097533448882821311588570897649
0.0286426911533663404678396477942956
0.00668482448938922740475019519860028
-0.0193999695469386388307782988276083
0.0131962921095527373607946721380589
-0.00142363533752891809783467677853379
-0.00569081731450817066412759667853352
0.00576341629406082560985217113222417
-0.00200953040304101268575767827219472
-0.00138241310354647511896352626325379
0.00235523537942597536210668729668636
-0.00134052593544293120653813909608214
-0.000124472012041684625103492011289663
0.000877718485310658054963862962235904
-0.000725780248549220293079370291315901
0.000153946002651081672732427784261987
0.000281002093489218044668996986822804
-0.000347033077495896376046600902527326
0.000153557047587153171615262184995174
0.0000631326094505423737466139726989411
-0.000148809498659804128090655494778209
0.0000997799319170460620050372271284211
-0.00000366756177968522484138187499300975
-0.0000560928643292255048420965789718678
0.0000541205773846002851156650754617952
-0.0000165509024241990403901897952115479
-0.0000171467417823198598606760175136922
0.0000258885580286696864110764494276036
-0.0000137290969049302627955313384274982
-0.00000286640686420803377244711837064614
0.0000109803604865810554310928802164877
-0.00000849771791124436153228043859514619
0.00000125914643600127456024329626150593
0.00000399293970401995517700352660353714
-0.00000449726868310084877916993424187367
0.00000176894518824413723563652493847337
0.00000109170674908376885093776045369610
-0.00000210342391231037589357119537437086
0.00000130161708299603955561297199526169
6.93796790980872151538233731691180E-8
-8.63552561198933240294736649885292E-7
7.67385763113287917587459691270367E-7
-1.89314055344153668337714983394592E-7
-2.94403306828973215629670453652457E-7
3.93099106151287980463564320621599E-7
-1.87924142642173789971818089630347E-7
'''

from decimal import *
getcontext().prec=33

listOfMultipliers  = [ Decimal(v) for v in data.split() ]

def arctan (x) :
    x = Decimal(str(x))
    if 1.05 >= x >= 0.45 : pass
    else : print ('\narctan(x): input is outside recommended range.',end='')
    y = Decimal(0)
    x0 = Decimal('0.746735417783721671737500140715213') # tan36.75
    x_minus_x0 = x - x0
    X = Decimal(1)
    status = 1
    for p in range(0,51) :
        toBeAdded = listOfMultipliers[p] * X
        if abs(toBeAdded) < Decimal('1e-31') :
            status = 0
            break
        y += toBeAdded
        X *= x_minus_x0
    if status :
        print ('\narctan(x): count expired.', end='')
    str1 = '''
arctan({}) = {}, count = {}
'''.format(x,y,p)
    print (str1.rstrip())
    return y

x close to x0
[edit | edit source]
x = Decimal('0.75')
arctan(x)

arctan(0.75) = 0.643501108793284386802809228717315, count = 12

When is close to result is achieved with only 12 passes through loop.

Testing with known values
[edit | edit source]

Check results using known combinations of and

For and other exact values of see Exact Values for Common Angles.

π = "3.14159265358979323846264338327950288419716939937510582097494459230781"
π = Decimal(π)
rt3 = Decimal(3).sqrt()
rt5 = Decimal(5).sqrt()
rt15 = Decimal(15).sqrt()

tan27 = rt5 - 1 - (5 - 2*rt5).sqrt()

tan30 = 1/rt3

v1 = 2 - (2-rt3)*(3+rt5) ; v2 = 2+ (2*(5-rt5)).sqrt()
tan33 = v1*v2/4

tan36 = (5-2*rt5).sqrt()

v1 = (2-rt3)*(3-rt5)-2 ; v2 = 2 - (2*(5+rt5)).sqrt()
tan39 = v1*v2/4

tan42 = ( rt15 + rt3 - (10 + 2*rt5).sqrt() )/2

tan45 = Decimal(1)

values = (
    ( 9*π/60, tan27, 27),
    (10*π/60, tan30, 30),
    (11*π/60, tan33, 33),
    (12*π/60, tan36, 36),
    (13*π/60, tan39, 39),
    (14*π/60, tan42, 42),
    (   π/ 4, tan45, 45),
)

for value in values :
    angleInRadians, tan, angleInDegrees = value
    y = arctan(tan)
    print ('for', angleInDegrees, 'degrees, difference =',  angleInRadians-y)

arctan(0.509525449494428810513706911250666) = 0.471238898038468985769396507491970, count = 41
for 27 degrees, difference = -4.5E-32

arctan(0.577350269189625764509148780501958) = 0.523598775598298873077107230546614, count = 34
for 30 degrees, difference = -3.1E-32

arctan(0.649407593197510576982062911311432) = 0.575958653158128760384817953601229, count = 27
for 33 degrees, difference = 1.3E-32

arctan(0.726542528005360885895466757480614) = 0.628318530717958647692528676655896, count = 17
for 36 degrees, difference = 4E-33

arctan(0.809784033195007148036991374235772) = 0.680678408277788535000239399710521, count = 23
for 39 degrees, difference = 3.7E-32

arctan(0.90040404429783994512047720388537) = 0.733038285837618422307950122765236, count = 33
for 42 degrees, difference = -1.9E-32

arctan(1) = 0.785398163397448309615660845819846, count = 43
for 45 degrees, difference = 3.0E-32

[edit | edit source]
tan24 = ( (50+22*rt5).sqrt() - 3*rt3 - rt15 ) / 2
tan46_5 = Decimal('1.05378012528096218058753672331544') # tan(46.5) 

values = (
    (24*π/180,   tan24,   24),
    (93*π/360, tan46_5, 46.5),
)

for value in values :
    angleInRadians, tan, angleInDegrees = value
    y = arctan(tan)
    print ('for x =', float(tan), 'difference =',  angleInRadians-y)

arctan(x): input is outside recommended range.
arctan(0.44522868530853616392236703064567) = 0.418879020478639098461685784437249, count = 47
for x = 0.44522868530853615 difference = 1.8E-32

arctan(x): input is outside recommended range.
arctan(1.05378012528096218058753672331544) = 0.811578102177363253269516207347250, count = 48
for x = 1.0537801252809622 difference = -4.4E-32

For the above calculation of is accurate to more than 30 places of decimals.

[edit | edit source]

If input is outside recommended limits, this does not necessarily mean that result is invalid.

If result is accurate to precision of python floats, 15 places of decimals.

arcsin(x)

[edit | edit source]

Simple differential equations eliminate the square root and make calculations so much easier.

Let

Then where and


Differentiating both sides:

Let

Then


Differentiating both sides:

Let

Then


When Calculation of more derivatives yields:

and so on.




As programming algorithm:

[edit | edit source]


As implemented in Python:

[edit | edit source]
from decimal import * # Default precision is 28.

π = ("3.14159265358979323846264338327950288419716939937510582097494459230781")
π = Decimal(π)

x = Decimal(2).sqrt()/2 # Expecting result of π/4

xSQ = x*x
X = x*xSQ

top = Decimal(1)
bottom = Decimal(2)

bottom1 = bottom*3
sum = x + X*top / bottom1

status = 1
for n in range(5,200,2) :
    X = X*xSQ
    top = top*(n-2)
    bottom = bottom*(n-1)
    bottom1 = bottom*n
    added = X*top/bottom1
    if (added < 1e-29) :
        status = 0
        break
    sum += added

if status :
    print ('error. count expired.')
else :
    print (x, sum==π/4, n)
0.707106781186547524400844362 True 171

In practice

[edit | edit source]

If is close to the calculation of will take forever.


If you limit to then and each term is guaranteed to be less than half the preceding term.


If let

Then

Integral of expression

[edit | edit source]

According to the reference "this expression cannot be integrated..." However, if we convert the expression to a Taylor series, the integral of the series is quite easily calculated.

Let

When and the following sequence can be produced.

where

and so on.

Taylor series of for close to

where

For python code produces the following:

c02 = -0.6931471805599453094172321215
c04 = 0.2402265069591007123335512632
c06 = -0.05550410866482157995314226378
c08 = 0.009618129107628477161979071575
c10 = -0.001333355814642844342341222199
c12 = 0.0001540353039338160995443709734
c14 = -0.00001525273380405984028002543902
c16 = 0.000001321548679014430948840375823
c18 = -1.017808600923969972749000760E-7
c20 = 7.054911620801123329875392184E-9
c22 = -4.445538271870811497596408561E-10
c24 = 2.567843599348820514199480240E-11
c26 = -1.369148885390412888089195400E-12
c28 = 6.778726354822545633449104318E-14
c30 = -3.132436707088428621634944443E-15
c32 = 1.357024794875514719311296624E-16
c34 = -5.533046532458242043485546100E-18
c36 = 2.130675335489117996020398479E-19
c38 = -7.773008428857356419088997166E-21
c40 = 2.693919438465583416972861154E-22
c42 = -8.891822206800239171648619811E-24

For close to or close to the Taylor series is a quite accurate representation of the original expression. When abs the abs(maximum difference) between expression and Taylor series is

For greater accuracy, greater precision may be specified in python or more terms after may be added.

The integral

where

Figure 1: Curves of and where is Taylor series representing for close to .

In figure to right, separating from to illustrate shapes of curves.

The correct value of .

When and .

To 24 places of decimals _____.

Figure 1: Curves of and where is integral of and represents integral of for close to .
In this example, constant of integration

If it were important to calculate the area under from to returns accurate to about 26 places of decimals.

sin(x) using (x - x0)

[edit | edit source]

Let

Let

Then

where is the Taylor series representing for values of close to or

If , then containing powers of through is sufficient to keep the error to

[edit | edit source]

Almost a sine curve

[edit | edit source]
Figure 1: Graph of representing for close to .

Graph to right was produced by Grapher on a Mac.

A python script produced the following data:

( (2^(0.5))/2 )(
 1  +(x-.785398163397448)

 -((x-.785398163397448)^2)/2
 -((x-.785398163397448)^3)/(2(3))

 +((x-.785398163397448)^4)/(24)
 +((x-.785398163397448)^5)/(120)

 -((x-.785398163397448)^6)/(720)
 -((x-.785398163397448)^7)/(5040)

 +((x-.785398163397448)^8)/(40320)
 +((x-.785398163397448)^9)/(362880)

 -((x-.785398163397448)^10)/(3628800)
 -((x-.785398163397448)^11)/(39916800)

 +((x-.785398163397448)^12)/(479001600)
 +((x-.785398163397448)^13)/(6227020800)

 -((x-.785398163397448)^14)/(87178291200)
 -((x-.785398163397448)^15)/(1307674368000)

 +((x-.785398163397448)^16)/(20922789888000)
 +((x-.785398163397448)^17)/(355687428096000)

 -((x-.785398163397448)^18)/(6402373705728000)
 -((x-.785398163397448)^19)/(121645100408832000)

 +((x-.785398163397448)^20)/(2432902008176640000)
 +((x-.785398163397448)^21)/(51090942171709440000)

 -((x-.785398163397448)^22)/(1124000727777607680000)
 -((x-.785398163397448)^23)/(25852016738884976640000)

 +((x-.785398163397448)^24)/(620448401733239439360000)
 +((x-.785398163397448)^25)/(15511210043330985984000000)

 -((x-.785398163397448)^26)/(403291461126605635584000000)
 -((x-.785398163397448)^27)/(10888869450418352160768000000)

 +((x-.785398163397448)^28)/(304888344611713860501504000000)
 +((x-.785398163397448)^29)/(8841761993739701954543616000000)
)

I highlighted the data, copied it with command C and pasted it into the input area of Grapher. Well done! Grapher.

Integral of 1/x

[edit | edit source]

The Taylor series for for close to is:

The integral of this series is:

The integral of

Therefore but what is the value of

Without when should be

Therefore, for close to

where

But what is the value of

Without when should be

Therefore or

For close to

where

Figure 1: Graph of representing for close to .
y = 0.693147180559945
+ ((1/(2^1))/1)(x - 2)^1
- ((1/(2^2))/2)(x - 2)^2
+ ((1/(2^3))/3)(x - 2)^3
- ((1/(2^4))/4)(x - 2)^4
+ ((1/(2^5))/5)(x - 2)^5
- ((1/(2^6))/6)(x - 2)^6
+ ((1/(2^7))/7)(x - 2)^7
...........................
...........................
- ((1/(2^42))/42)(x - 2)^42
+ ((1/(2^43))/43)(x - 2)^43
- ((1/(2^44))/44)(x - 2)^44
+ ((1/(2^45))/45)(x - 2)^45
- ((1/(2^46))/46)(x - 2)^46
+ ((1/(2^47))/47)(x - 2)^47
- ((1/(2^48))/48)(x - 2)^48
+ ((1/(2^49))/49)(x - 2)^49

Calculating ln(x)

[edit | edit source]

This section presents a system for calculating for knowing only that

# python code
L1 = [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 2.8, 
    3.0, 3.3, 3.6, 3.9, 4.2, 4.6, 5.0, 5.5, 6.0, 6.6, 7.2, 7.9, 8.6, 9.3, 10.0]

where L1 is a list containing values of in which each value after the first is % more than the preceding value.

# python code
from decimal import *
getcontext().prec=53 # Preparing for values containing 50 places of decimals.
almostZero = Decimal('1e-' + str( getcontext().prec ))

L1 = [ Decimal(str(v)) for v in L1 ]

def ln_x (x, x0, C=0) :
    '''
    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).
    '''
    x, x0, C = [ Decimal(str(v)) for v in (x,x0,C) ]
    x_minus_x0 = x-x0;
#    print ('x,x0,x_minus_x0 =',x,x0,x_minus_x0)
    sum = 0
    progressiveValue = 1
    status = 1 ; limit = 4*getcontext().prec
    multiplier = x_minus_x0/x0
    for p in range (1, limit, 2) :
        progressiveValue *= multiplier
        added = progressiveValue / p
        sum += added

        progressiveValue *= multiplier
        added = progressiveValue / (p+1)

        if (abs(added) < almostZero) :
            status = 0
            break
        sum -= added
    if (status) :
        print ('ln_x error: count expired, p =',p)
        exit (95)
    return sum+C

The performance of the above code is better than logarithmic to base . This means, for example, if contains 60 significant decimal digits, the above code produces a result with fewer than 30 passes through the loop because each iteration of the lop performs two operations.

L1 is designed so that multiplier is always When is very close to time to calculate is greatly reduced.

Figure 1: Graph of representing for close to .
When value the series diverges.
In this case, when
y = ln(7.9)
+ ((1/((7.9)^(1)))/(1))((x - 7.9)^(1))
- ((1/((7.9)^(2)))/(2))((x - 7.9)^(2))
+ ((1/((7.9)^(3)))/(3))((x - 7.9)^(3))
- ((1/((7.9)^(4)))/(4))((x - 7.9)^(4))
+ ((1/((7.9)^(5)))/(5))((x - 7.9)^(5))
- ((1/((7.9)^(6)))/(6))((x - 7.9)^(6))
+ ((1/((7.9)^(7)))/(7))((x - 7.9)^(7))
- ((1/((7.9)^(8)))/(8))((x - 7.9)^(8))
+ ((1/((7.9)^(9)))/(9))((x - 7.9)^(9))
.....................
.....................
- ((1/((7.9)^(22)))/(22))((x - 7.9)^(22))
+ ((1/((7.9)^(23)))/(23))((x - 7.9)^(23))
- ((1/((7.9)^(24)))/(24))((x - 7.9)^(24))
+ ((1/((7.9)^(25)))/(25))((x - 7.9)^(25))
- ((1/((7.9)^(26)))/(26))((x - 7.9)^(26))
+ ((1/((7.9)^(27)))/(27))((x - 7.9)^(27))
- ((1/((7.9)^(28)))/(28))((x - 7.9)^(28))
+ ((1/((7.9)^(29)))/(29))((x - 7.9)^(29))

The next piece of code progressively calculates and puts the calculated values in dictionary dict2.

dict2 = dict()
dict2[Decimal('1.0')] = Decimal(0)

for p in range(1, len(L1)) :
    x = L1[p]
    x0 = L1[p-1]
    C = dict2[x0]
#    print ('L1[{}]={}'.format(p,L1[p]))
    ln = ln_x (x, x0, C)
    dict2[x] = ln

print ('dict2 = {')
for x0 in dict2 :
    print ("Decimal('{}'):  +Decimal('{}'),".format( (' '+str(x0))[-4:], dict2[x0]) )
print ('}')
dict2 = {
Decimal(' 1.0'):  +Decimal('0'),
Decimal(' 1.1'):  +Decimal('0.095310179804324860043952123280765092220605365308644199'),
Decimal(' 1.2'):  +Decimal('0.18232155679395462621171802515451463319738933791448698'),
Decimal(' 1.3'):  +Decimal('0.26236426446749105203549598688095439720416645613143414'),
Decimal(' 1.4'):  +Decimal('0.33647223662121293050459341021699209011148337531334347'),
Decimal(' 1.5'):  +Decimal('0.40546510810816438197801311546434913657199042346249420'),
Decimal(' 1.6'):  +Decimal('0.47000362924573555365093703114834206470089904881224805'),
Decimal(' 1.7'):  +Decimal('0.53062825106217039623154316318876232798710152395697182'),
Decimal(' 1.8'):  +Decimal('0.58778666490211900818973114061886376976937976137698120'),
Decimal(' 1.9'):  +Decimal('0.64185388617239477599103597720348932963627777267035586'),
Decimal(' 2.0'):  +Decimal('0.69314718055994530941723212145817656807550013436025527'),
Decimal(' 2.2'):  +Decimal('0.78845736036427016946118424473894166029610549966889947'),
Decimal(' 2.4'):  +Decimal('0.87546873735389993562895014661269120127288947227474225'),
Decimal(' 2.6'):  +Decimal('0.95551144502743636145272810833913096527966659049168941'),
Decimal(' 2.8'):  +Decimal('1.0296194171811582399218255316751686581869835096735987'),
Decimal(' 3.0'):  +Decimal('1.0986122886681096913952452369225257046474905578227494'),
Decimal(' 3.3'):  +Decimal('1.1939224684724345514391973602032907968680959231313936'),
Decimal(' 3.6'):  +Decimal('1.2809338454620643176069632620770403378448798957372364'),
Decimal(' 3.9'):  +Decimal('1.3609765531356007434307412238034801018516570139541836'),
Decimal(' 4.2'):  +Decimal('1.4350845252893226218998386471395177947589739331360929'),
Decimal(' 4.6'):  +Decimal('1.5260563034950493162059934985840084789167789605719180'),
Decimal(' 5.0'):  +Decimal('1.6094379124341003746007593332261876395256013542685177'),
Decimal(' 5.5'):  +Decimal('1.7047480922384252346447114565069527317462067195771619'),
Decimal(' 6.0'):  +Decimal('1.7917594692280550008124773583807022727229906921830047'),
Decimal(' 6.6'):  +Decimal('1.8870696490323798608564294816614673649435960574916489'),
Decimal(' 7.2'):  +Decimal('1.9740810260220096270241953835352169059203800300974917'),
Decimal(' 7.9'):  +Decimal('2.0668627594729758101549540867970467145724397357938367'),
Decimal(' 8.6'):  +Decimal('2.1517622032594620488720831801196593960335348306130377'),
Decimal(' 9.3'):  +Decimal('2.2300144001592102533064181067805187074963279996745685'),
Decimal('10.0'):  +Decimal('2.3025850929940456840179914546843642076011014886287730'),
}

A quick check:

ln(2.2) - (ln(1.1) + ln(2.0)) = 0E-50
ln(2.4) - (ln(1.2) + ln(2.0)) = 0E-50
ln(2.6) - (ln(1.3) + ln(2.0)) = 0E-50
ln(2.8) - (ln(1.4) + ln(2.0)) = 0E-50
ln(3.0) - (ln(1.5) + ln(2.0)) = -0E-50
ln(3.3) - (ln(1.1) + ln(3.0)) = 0E-50
ln(3.6) - (ln(1.2) + ln(3.0)) = 0E-50
ln(3.6) - (ln(1.8) + ln(2.0)) = -0E-50
ln(3.9) - (ln(1.3) + ln(3.0)) = 0E-50
ln(4.2) - (ln(1.4) + ln(3.0)) = 0E-50
ln(5.5) - (ln(1.1) + ln(5.0)) = 0E-50
ln(6.0) - (ln(1.2) + ln(5.0)) = 0E-50
ln(6.0) - (ln(2.0) + ln(3.0)) = 0E-50
ln(6.6) - (ln(1.1) + ln(6.0)) = 0E-50
ln(6.6) - (ln(2.2) + ln(3.0)) = 0E-50
ln(6.6) - (ln(3.3) + ln(2.0)) = 0E-50
ln(7.2) - (ln(1.2) + ln(6.0)) = 0E-50
ln(7.2) - (ln(2.4) + ln(3.0)) = 0E-50
ln(10.0) - (ln(5.0) + ln(2.0)) = 0E-50

Put the data from dict2 into 2 tuples Tx0, Tln_x0

Tx0 = tuple(L1)
Tln_x0 = tuple([ dict2[v] for v in Tx0 ])

Calculate the decision points.

L1 = []
for p in range (0, len(Tx0)-1) :
    a,b = Tx0[p], Tx0[p+1]
    dp = 2*a*b/(a+b)
    L1 += [ dp ]
Tdp = tuple(L1)

Display the three tuples.

for T in ('Tx0', 'Tln_x0', 'Tdp') :
    t = eval(T)
    print (T, '= (')
    for v in t :
        print ("""+Decimal('{}'),""".format(v))
    print (')')
    print ()

Previous code was used to produce three tuples. Operational code follows:


Values of

Tx0 = ( Decimal('1'), Decimal('1.1'), Decimal('1.2'), Decimal('1.3'), Decimal('1.4'), Decimal('1.5'), Decimal('1.6'), Decimal('1.7'), Decimal('1.8'), Decimal('1.9'), Decimal('2.0'), Decimal('2.2'), Decimal('2.4'), Decimal('2.6'), Decimal('2.8'), Decimal('3.0'), Decimal('3.3'), Decimal('3.6'), Decimal('3.9'), Decimal('4.2'), Decimal('4.6'), Decimal('5.0'), Decimal('5.5'), Decimal('6.0'), Decimal('6.6'), Decimal('7.2'), Decimal('7.9'), Decimal('8.6'), Decimal('9.3'), Decimal('10.0'), )


Values of

Tln_x0 = ( +Decimal('0'), +Decimal('0.095310179804324860043952123280765092220605365308644199'), +Decimal('0.18232155679395462621171802515451463319738933791448698'), +Decimal('0.26236426446749105203549598688095439720416645613143414'), +Decimal('0.33647223662121293050459341021699209011148337531334347'), +Decimal('0.40546510810816438197801311546434913657199042346249420'), +Decimal('0.47000362924573555365093703114834206470089904881224805'), +Decimal('0.53062825106217039623154316318876232798710152395697182'), +Decimal('0.58778666490211900818973114061886376976937976137698120'), +Decimal('0.64185388617239477599103597720348932963627777267035586'), +Decimal('0.69314718055994530941723212145817656807550013436025527'), +Decimal('0.78845736036427016946118424473894166029610549966889947'), +Decimal('0.87546873735389993562895014661269120127288947227474225'), +Decimal('0.95551144502743636145272810833913096527966659049168941'), +Decimal('1.0296194171811582399218255316751686581869835096735987'), +Decimal('1.0986122886681096913952452369225257046474905578227494'), +Decimal('1.1939224684724345514391973602032907968680959231313936'), +Decimal('1.2809338454620643176069632620770403378448798957372364'), +Decimal('1.3609765531356007434307412238034801018516570139541836'), +Decimal('1.4350845252893226218998386471395177947589739331360929'), +Decimal('1.5260563034950493162059934985840084789167789605719180'), +Decimal('1.6094379124341003746007593332261876395256013542685177'), +Decimal('1.7047480922384252346447114565069527317462067195771619'), +Decimal('1.7917594692280550008124773583807022727229906921830047'), +Decimal('1.8870696490323798608564294816614673649435960574916489'), +Decimal('1.9740810260220096270241953835352169059203800300974917'), +Decimal('2.0668627594729758101549540867970467145724397357938367'), +Decimal('2.1517622032594620488720831801196593960335348306130377'), +Decimal('2.2300144001592102533064181067805187074963279996745685'), +Decimal('2.3025850929940456840179914546843642076011014886287730'), )


Decision points:

Tdp = ( +Decimal('1.0476190476190476190476190476190476190476190476190476'), +Decimal('1.1478260869565217391304347826086956521739130434782609'), +Decimal('1.248'), +Decimal('1.3481481481481481481481481481481481481481481481481481'), +Decimal('1.4482758620689655172413793103448275862068965517241379'), +Decimal('1.5483870967741935483870967741935483870967741935483871'), +Decimal('1.6484848484848484848484848484848484848484848484848485'), +Decimal('1.7485714285714285714285714285714285714285714285714286'), +Decimal('1.8486486486486486486486486486486486486486486486486486'), +Decimal('1.9487179487179487179487179487179487179487179487179487'), +Decimal('2.0952380952380952380952380952380952380952380952380952'), +Decimal('2.2956521739130434782608695652173913043478260869565217'), +Decimal('2.496'), +Decimal('2.6962962962962962962962962962962962962962962962962963'), +Decimal('2.8965517241379310344827586206896551724137931034482759'), +Decimal('3.1428571428571428571428571428571428571428571428571429'), +Decimal('3.4434782608695652173913043478260869565217391304347826'), +Decimal('3.744'), +Decimal('4.0444444444444444444444444444444444444444444444444444'), +Decimal('4.3909090909090909090909090909090909090909090909090909'), +Decimal('4.7916666666666666666666666666666666666666666666666667'), +Decimal('5.2380952380952380952380952380952380952380952380952381'), +Decimal('5.7391304347826086956521739130434782608695652173913043'), +Decimal('6.2857142857142857142857142857142857142857142857142857'), +Decimal('6.8869565217391304347826086956521739130434782608695652'), +Decimal('7.5337748344370860927152317880794701986754966887417219'), +Decimal('8.2351515151515151515151515151515151515151515151515152'), +Decimal('8.9363128491620111731843575418994413407821229050279330'), +Decimal('9.6373056994818652849740932642487046632124352331606218'), )

At each decision point is assigned to the next low value or the next high value of For example, if is between the decision point is This means that the ratio and the maximum value of abs

During creation of Tln_x0 the maximum value of During normal operations after creation of Tln_x0, maximum value of abs between


Choose a suitable value of x0 with the value of its natural log.

def choose_x0_C (x) :
    '''
    (x0, C) = choose_x0_C (x)
    '''
    if (10 >= x >= 1) : pass
    else: exit (93)

    for p in range (len(Tx0)-2, -1, -1):
        if (x >= Tx0[p]) :
            if (x >= Tdp[p]) : return (Tx0[p+1], Tln_x0[p+1])
            return (Tx0[p], Tln_x0[p])
    exit(92)

Ready to calculate, for example,

x = Decimal('3.456789')
(x0, C) = choose_x0_C (x)
ln_x_ = ln_x (x, x0, C)
print ('ln({}) = {}'.format(x, ln_x_.quantize(Decimal('1e-50'))))
ln(3.456789) = 1.24034_01234_96758_02986_53847_82231_30004_00340_53893_89110 # displayed with 50 places of decimals.

Testing ln(x)

[edit | edit source]

Choose random numbers so that

Produce values

Calculate product

Produce value

If and

Verify that

# python code
import random

ln_10 = Tln_x0[-1]
fiftyPlacesOfDecimals = Decimal('1e-50')

def randomNumber() :
    s1 = str(random.getrandbits(getcontext().prec * 4))
    d1 = Decimal(s1[0] + '.' + s1[1:])
    if (d1 == 0) : d1 = randomNumber()
    while (d1 < 1) : d1 *= 10
    return d1

d1 = randomNumber()
d2 = randomNumber()

(x0, C) = choose_x0_C (d1)
ln_d1_ = ln_x (d1, x0, C)

(x0, C) = choose_x0_C (d2)
ln_d2_ = ln_x (d2, x0, C)

product = d1*d2
add_ln10 = 0
if (product > 10) :
    product /= 10
    add_ln10 += 1

(x0, C) = choose_x0_C (product)
ln_product_ = ln_x (product, x0, C)
if (add_ln10) : ln_product_ += ln_10

difference = (ln_product_ - ( ln_d1_ + ln_d2_ )).quantize(fiftyPlacesOfDecimals)

print ('''
d1          = {}
ln_d1_      = {}
d2          = {}
ln_d2_      = {}
ln_product_ = {}
'''.format(
d1,ln_d1_ ,
d2,ln_d2_ ,
ln_product_ ,
))

if difference :  print ('''
difference  = {} ****
'''.format(
difference,
))

For example: During testing, successive invocations of the above code produced:

d1          = 3.300463847393627263496303126765085976697315885228780009201595937
ln_d1_      = 1.1940630184110798505583266934968432937656468440595029
d2          = 4.727915623201914684885711302927600487326893972103794963997766615
ln_d2_      = 1.5534844337520634527664958773360448454701186698422347
ln_product_ = 2.7475474521631433033248225708328881392357655139017377
d1          = 6.56429212435850275252301147228535243835226966080458915176241218
ln_d1_      = 1.8816446762531860392218213681767770852191644273705970
d2          = 8.15468991518212749204100104755219361919087392341006662123706307
ln_d2_      = 2.0985932114606734087366302984138612677420896519457258
ln_product_ = 3.9802378877138594479584516665906383529612540793163228
[edit | edit source]