Logarithm Function (Python)

From LiteratePrograms

Jump to: navigation, search
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
Views