Logarithm Function (Python)
From LiteratePrograms
- Other implementations: Pascal | Python | Python, functional
Contents |
Logarithm function
The logarithm function performs a mathematical operation that is the inverse of an exponentiation function (raising a constant, the base, to a power). The logarithm of a number x in base b is any number n such that x = bn. It is usually written as
Finding the logarithm in base b of a positive real number x can be done in two parts:
- Finding the integer part of the logarithm
- Finding the fractional part of the logarithm
1. Finding the integer part
Finding the integer part can be done by simply dividing the number x by the base b until it is no longer larger than the base b. The integer part is the number of iterations we do the division.
For example: Find log base 3 of 161.64
iteration no 1 | 161.64 / 3 = 53.88 | |
iteration no 2 | 53.88 / 3 = 17.96 | |
iteration no 3 | 17.96 / 3 = 5.9866 | |
iteration no 4 | 5.9866 / 3 = 1.9955 |
As it takes 4 iterations, the integer part of the logarithm is 4.
2. Finding the fractional part
To find the fractional part, we use the fact that multiplying a logarithm number by two is equivalent to squaring.
Example: find fractional part of 161.64 in log base 3
- thus
Next we square both sides
Because 3.98 is greater than 3, we can write:
- thus
Next we concentrate on f1
- becomes
Next we repeat the trick of squaring both sides
Because 1.76 is less than 3, we can write:
thus:
Next we concentrate on f2
- becomes
With the general procedure established above, we can calculate , , , and so on.
Recapping, we have:
and
thus creating
In general, we have
or
- Where is either 1 or 0
Source Code
<<logN.py>>= #!/usr/bin/python from __future__ import division import math def logN(X, base=math.e, epsilon=1e-12): # logN is logarithm function with the default base of e integer = 0 if X < 1 and base < 1: raise ValueError, "logarithm cannot compute" while X < 1: integer -= 1 X *= base while X >= base: integer += 1 X /= base partial = 0.5 # partial = 1/2 # list = [] # Prepare an empty list, it seems useless X *= X # We perform a squaring decimal = 0.0 while partial > epsilon: if X >= base: # If X >= base then a_k is 1 decimal += partial # Insert partial to the front of the list X = X / base # Since a_k is 1, we divide the number by the base partial *= 0.5 # partial = partial / 2 X *= X # We perform the squaring again return (integer + decimal) if __name__ == '__main__': value = 4.5 print " X = ", value print " ln(X) = ", logN(value) print " log4(X) = ", logN(value, base=4)
Sample Run
$ python logN.py X = 4.5 ln(X)= 1.50407739678 log4(X)= 1.08496250072
Extension
Given the equation:
- The algorithm above computes
- However, by modifying the algorithm slightly, it's possible to compute
This will allow us to stop the computation at a particular decimal place.
Source Code
<<logNdp.py>>= #!/usr/bin/python from __future__ import division import math # Note: compute the log of X>=1. Doesn't work for X<1. Ex: logN(0.5) returns -1.698970... instead of -0.301029... def logN(X, base=math.e, decimalplaces=12): integer = 0 while X < 1: integer -= 1 X *= base while X >= base: integer += 1 X /= base result = str(integer) + '.' while decimalplaces > 0: X = X ** 10 # Calc X to the 10th power digit = 0 while X >= base: digit += 1 X /= base result += str(digit) decimalplaces -= 1 return result if __name__ == '__main__': value = 4.5 print " X = ", value print " 3 decimal places LOG(X) = ", logN(value, base=10, decimalplaces=3) print " 6 decimal places LOG(X) = ", logN(value, base=10, decimalplaces=6) print "12 decimal places LOG(X) = ", logN(value, base=10)
Sample Run
$ python logNdp.py X = 4.5 3 decimal places LOG(X) = 0.653 6 decimal places LOG(X) = 0.653212 12 decimal places LOG(X) = 0.653212513775
To compute logarithm of 0<X<1 and X>=1
(created in Python 3.1 using modified source as contained on this page)
from __future__ import division import math from os import * def logN(X, base=math.e, decimalplaces=12): if X>=1: integer = 0 while X < 1: integer -= 1 X *= base while X >= base: integer += 1 X /= base result = str(integer) + '.' while decimalplaces > 0: X = X ** 10 # Calc X to the 10th power digit = 0 while X >= base: digit += 1 X /= base result += str(digit) decimalplaces -= 1 return result #end if else: reverse=X*base reverse=base/reverse result = logN(reverse,base,decimalplaces) result = float(result) * (-1.0) #must cast result as float to calculate. return result ################ # Main Program # ################ value=1 #sentinel value to start loop while (value > 0): print("Enter the value for log (base 10), enter zero or a negative to quit ->") value=float(input()) base = 10 if (value > 0): print(" X = ", value) print(" 3 decimal places LOG(X) = ", logN(value, base=10, decimalplaces=3)) print(" 6 decimal places LOG(X) = ", logN(value, base=10, decimalplaces=6)) print("12 decimal places LOG(X) = ", logN(value, base=10, decimalplaces=12)) #end if #end while print("Thanks for using this program!")
Example Run
4.5 X = 4.5 3 decimal places LOG(X) = 0.653 6 decimal places LOG(X) = 0.653212 12 decimal places LOG(X) = 0.653212513775 Enter the value for log (base 10), enter a negative to quit -> .5 X = 0.5 3 decimal places LOG(X) = -0.301 6 decimal places LOG(X) = -0.301029 12 decimal places LOG(X) = -0.301029995663 Enter the value for log (base 10), enter a negative to quit ->
Download code |