Starting from:

$30

CS3430-Assignment 4 Differentiation of y = ex and y = lnx and Logarithmic Differentiation Solved

Problem 1: Differentiation of Exponential and Logarithmic Functions
Extend your differentiation engine in deriv.py with the rules for differentiating y = ex and y = lnx. Your extensions should handle such variants of ex as Cekx, where C and k are reals, and eg(x), where g(x) is a differentiable function. Your extensions should also cover such variants of lnx as ln|x|, (lnx)k, where k is a real, and ln(g(x)), where g(x) is a differentiable function. Use the implementations of the absolute value and natural logarithm classes in absv.py and ln.py, respectively, to represent function expressions and make appropriate changes to tof.py to convert the outputs of your deriv function to regular Python functions for unit testing.

Test 01
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from tof import tof from deriv import deriv

def test_01():

print(’\n***** Test 01 ************’) fex = make_e_expr(make_prod(make_const(5.0), make_pwr(’x’, 1.0)))

print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: 5.0*(math.e**(5.0*x)) for i in range(10): print(drvf(i), gt(i)) assert abs(gt(i) - drvf(i)) <= 0.001

print(’Test 01: pass’)

Here is the output of test_01 in the Py shell.

***** Test 01 ************

(2.71828182846^(5.0*(x^1.0)))

((2.71828182846^(5.0*(x^1.0)))*(5.0*(1.0*(x^0.0))))

(5.0, 5.0)

(742.0657955128829, 742.0657955128829)

(110132.32897403352, 110132.32897403352)

(16345086.862360539, 16345086.862360539) (2425825977.048949, 2425825977.048949)

(360024496686.92883, 360024496686.92883) (53432372907622.23, 53432372907622.23)

(7930067261567139.0, 7930067261567139.0)

(1.1769263341850975e+18, 1.1769263341850975e+18)

(1.7467135528742506e+20, 1.7467135528742506e+20) Test 01: pass

Test 02
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus from tof import tof from deriv import deriv

def test_02():

print(’\n***** Test 02 ************’) fex = make_e_expr(make_plus(make_pwr(’x’, 2.0),

make_const(-1.0)))

print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: 2*x*(math.e**(x**2 - 1.0)) err = 0.0001 for i in range(10): print(drvf(i), gt(i))

assert abs(gt(i) - drvf(i)) <= err print(’Test 01: pass’)

Here is the output of test_02 in the Py shell.

***** Test 02 ************

(2.71828182846^((x^2.0)+-1.0))

((2.71828182846^((x^2.0)+-1.0))*((2.0*(x^1.0))+0.0))

(0.0, 0.0)

(2.0, 2.0)

(80.34214769275066, 80.34214769275066)

(17885.74792225036, 17885.74792225036)

(26152138.979776863, 26152138.979776863)

(264891221298.4344, 264891221298.4344)

(1.9032161427761132e+16, 1.9032161427761132e+16) (9.82343027693666e+21, 9.82343027693666e+21)

(3.6700530551513636e+28, 3.6700530551513636e+28)

(9.973120291908276e+35, 9.973120291908276e+35) Test 02: pass

Test 03
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot from tof import tof from deriv import deriv

def test_03(self):

print(’\n***** Test 03 ************’) fex1 = make_quot(make_const(-1.0), make_pwr(’x’, 1.0)) fex2 = make_e_expr(make_plus(make_pwr(’x’, 1.0), fex1)) print(fex2) drv = deriv(fex2) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None def gt_drvf(x):

d = (x - 1.0/x)

return (math.e**d)*(1.0 + 1.0/(x**2))

err = 0.0001 for i in range(1, 10):

print drvf(i), gt_drvf(i) assert abs(gt_drvf(i) - drvf(i)) <= err

print(’Test 03: pass’)

Here is the output of test_03 in the Py shell.

(2.71828182846^((x^1.0)+(-1.0/(x^1.0))))

((2.71828182846^((x^1.0)+(-1.0/(x^1.0))))*((1.0*(x^0.0))+((((x^1.0)*0.0)+

(-1.0*(-1.0*(1.0*(x^0.0)))))/((x^1.0)^2.0))))

2.0 2.0

5.60211133792 5.60211133792

15.9910178835 15.9910178835

45.1786496251 45.1786496251

126.370834219 126.370834219

350.981076014 350.981076014

970.048009362 970.048009362

2671.79066202 2671.79066202

7340.4760869 7340.4760869 Test 03: pass

Test 04
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot from tof import tof from deriv import deriv

def test_04():

print(’\n***** Test 04 ************’) n = make_prod(make_const(3.0), make_e_expr(make_prod(make_const(2.0), make_pwr(’x’, 1.0))))

d = make_plus(make_const(1.0), make_pwr(’x’, 2.0)) fex = make_quot(n, d) print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None def gt_drvf(x): n = 6.0*(math.e**(2.0*x))*(x**2 - x + 1.0) d = (1 + x**2)**2 return n/d

for i in range(-10, 10): print drvf(i), gt_drvf(i) assert abs(gt_drvf(i) - drvf(i)) <= 0.001

print(’Test 04: pass’)

Here is the output of test_04 in the Py shell.

***** Test 04 ************

((3.0*(2.71828182846^(2.0*(x^1.0))))/(1.0+(x^2.0))) ((((1.0+(x^2.0))*(3.0*((2.71828182846^(2.0*(x^1.0)))*(2.0*(1.0*(x^0.0))))))

+(-1.0*((3.0*(2.71828182846^(2.0*(x^1.0))))*(0.0+(2.0*(x^1.0))))))/

((1.0+(x^2.0))^2.0))

1.3456801417e-10 1.3456801417e-10

1.23669972347e-09 1.23669972347e-09

1.16663684088e-08 1.16663684088e-08

1.13753128773e-07 1.13753128773e-07

1.15793045081e-06 1.15793045081e-06

1.24916966506e-05 1.24916966506e-05

0.000146257062684 0.000146257062684

0.0019334266978 0.0019334266978

0.0307702733331 0.0307702733331

0.609008774565 0.609008774565

6.0 6.0

11.0835841484 11.0835841484

39.3106680239 39.3106680239

169.440093267 169.440093267

804.549214496 804.549214496

4105.52468956 4105.52468956

22112.7766281 22112.7766281

124108.762126 124108.762126

719301.727341 719301.727341

4277077.10918 4277077.10918 Test 04: pass

Test 05
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from tof import tof from deriv import deriv

def test_05():

print(’\n***** Test 05 ************’) fex = make_pwr_expr(make_ln(make_pwr(’x’, 1.0)), 5.0) print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: (5.0*(math.log(x, math.e)**4))/x

err = 0.0001

for i in range(1, 5): print(drvf(i), gt(i)) assert abs(gt(i) - drvf(i)) <= err

print(’Test 05: pass’)

Here is the output of test_05 in the Py shell.

***** Test 05 ************

(ln(x^1.0)^5.0)

((5.0*(ln(x^1.0)^4.0))*((1.0/(x^1.0))*(1.0*(x^0.0))))

(0.0, 0.0)

(0.5770877464577086, 0.5770877464577086)

(2.427876323344287, 2.427876323344287)

(4.616701971661668, 4.616701971661668) Test 05: pass

Test 06
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from tof import tof from deriv import deriv

def test_06():

print(’\n***** Test 06 ************’) fex = make_prod(make_pwr(’x’, 1.0), make_ln(make_pwr(’x’, 1.0)))

print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: 1.0 + math.log(x, math.e) err = 0.0001 for i in range(1, 10):

print(drvf(i), gt(i))

assert abs(gt(i) - drvf(i)) <= err print(’Test 06: pass’) Here is the output of test_06 in the Py shell. ***** Test 06 ************

((x^1.0)*ln(x^1.0))

(((x^1.0)*((1.0/(x^1.0))*(1.0*(x^0.0))))+(ln(x^1.0)*(1.0*(x^0.0))))

(1.0, 1.0)

(1.6931471805599454, 1.6931471805599454)

(2.09861228866811, 2.09861228866811)

(2.386294361119891, 2.386294361119891)

(2.6094379124341005, 2.6094379124341005) (2.791759469228055, 2.791759469228055)

(2.9459101490553135, 2.9459101490553135)

(3.0794415416798357, 3.0794415416798357)

(3.1972245773362196, 3.1972245773362196) Test 06: pass

Test 07
Let’s do

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from tof import tof from deriv import deriv

def test_07():

print(’\n***** Test 07 ************’) fex0 = make_prod(make_pwr(’x’, 1.0), make_e_expr(make_pwr(’x’, 1.0)))

fex = make_ln(fex0) print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: (x + 1.0)/x err = 0.0001 for i in range(1, 10): print(drvf(i), gt(i)) assert abs(gt(i) - drvf(i)) <= err

for i in range(-10, -1): print(drvf(i), gt(i)) assert abs(gt(i) - drvf(i)) <= 0.001

print(’Test 07: pass’) Here is the output of test_07 in the Py shell. ***** Test 07 ************ ln((x^1.0)*(2.71828182846^(x^1.0))) (((1.0/(x^1.0))*(1.0*(x^0.0)))+((1.0/(2.71828182846^(x^1.0)))* x‘((2.71828182846^(x^1.0))*(1.0*(x^0.0)))))

(2.0, 2.0)

(1.5, 1.5)

(1.3333333333333333, 1.3333333333333333)

(1.25, 1.25)

(1.2, 1.2)

(1.1666666666666667, 1.1666666666666667)

(1.1428571428571428, 1.1428571428571428) (1.125, 1.125)

(1.1111111111111112, 1.1111111111111112) (0.9, 0.9)

(0.8888888888888888, 0.8888888888888888) (0.875, 0.875)

(0.8571428571428572, 0.8571428571428571)

(0.8333333333333334, 0.8333333333333334)

(0.8, 0.8)

(0.75, 0.75)

(0.6666666666666667, 0.6666666666666666)

(0.5, 0.5) Test 07: pass

Test 08
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from maker import make_absv from tof import tof from deriv import deriv

def test_08():

print(’\n***** Test 08 ************’) fex = make_ln(make_absv(make_pwr(’x’, 1.0))) print(fex) drv = deriv(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None gt = lambda x: 1.0/x err = 0.0001

for i in range(1, 10): print(drvf(i), gt(i)) assert abs(gt(i) - drvf(i)) <= err

print(’Test 08: pass’)

Here is the output of test_08 in the Py shell.

***** Test 08 ************ ln|(x^1.0)| ((x^1.0)^-1.0)

(1.0, 1.0)

(0.5, 0.5)

(0.3333333333333333, 0.3333333333333333)

(0.25, 0.25)

(0.2, 0.2)

(0.16666666666666666, 0.16666666666666666)

(0.14285714285714285, 0.14285714285714285)

(0.125, 0.125)

(0.1111111111111111, 0.1111111111111111) Test 08: pass

Problem 2: Logarithmic Differentiation
Implement logarithmic differentiation. Specifically, write a function logdiff(expr) and save it in deriv.py. This function takes a function representation of a product and computes its derivative.

Test 09
Let’s do

import math

from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from maker import make_absv from tof import tof from deriv import deriv from deriv import logdiff

def test_09(self):

print(’\n***** Test 09 ************’) fex = make_prod(make_pwr(’x’, 1.0), make_prod(make_plus(make_pwr(’x’, 1.0), make_const(1.0)),

make_plus(make_pwr(’x’, 1.0),

make_const(2.0))))

drv = logdiff(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None def gt_drvf(x):

z = x*(x + 1.0)*(x + 2.0) z2 = (1.0/x + 1.0/(x + 1.0) + 1.0/(x + 2.0)) return z * z2

err = 0.0001 for i in range(1, 10):

print(drvf(i), gt_drvf(i)) assert abs(gt_drvf(i) - drvf(i)) <= err

for i in range(-10, -1):

if i == -1 or i == -2: continue

print(drvf(i), gt_drvf(i)) assert abs(gt_drvf(i) - drvf(i)) <= err

print(’Test 09: pass’)

Here is the output of test_09 in the Py shell. Note that the output of logarithmic differentiation typically has variables in denominators. So be careful to specify the appropriate ranges in your unit tests.

***** Test 09 ************

(((x^1.0)*(((x^1.0)+1.0)*((x^1.0)+2.0)))*(((1.0/(x^1.0))*(1.0*(x^0.0)))+

(((1.0/((x^1.0)+1.0))*((1.0*(x^0.0))+0.0))+((1.0/((x^1.0)+2.0))*

((1.0*(x^0.0))+0.0)))))

(11.0, 11.0)

(26.0, 26.0)

(47.0, 46.99999999999999)

(74.0, 74.0)

(107.0, 107.0)

(146.0, 146.0)

(191.0, 191.0)

(242.00000000000003, 242.00000000000003) (299.0, 299.0)

(242.00000000000003, 242.00000000000003)

(191.0, 191.0)

(146.0, 146.0)

(107.0, 107.0)

(74.0, 74.0)

(46.99999999999999, 47.0)

(26.0, 26.0)

(11.0, 11.0)

Test 09: pass

Test 10
Let’s do dxd (x2 + 1)(x3 − 3)(2x + 5).

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from maker import make_absv from tof import tof from deriv import deriv from deriv import logdiff

def test_10():

print(’\n***** Test 10 ************’) fex1 = make_plus(make_pwr(’x’, 2.0), make_const(1.0)) fex2 = make_plus(make_pwr(’x’, 3.0), make_const(-3.0)) fex3 = make_plus(make_prod(make_const(2.0), make_pwr(’x’, 1.0)),

make_const(5.0))

fex = make_prod(fex1, make_prod(fex2, fex3)) print(fex) drv = logdiff(fex) assert not drv is None print(drv) drvf = tof(drv) assert not drvf is None def gt_drvf(x):

z = (x**2 + 1.0)*(x**3 - 3.0)*(2*x + 5.0) z2 = ((2.0*x)/(x**2 + 1) + (3.0*(x**2))/(x**3 - 3.0) \

+ 2.0/(2*x + 5.0)) return z * z2

for i in range(1, 10):

print(drvf(i), gt_drvf(i)) assert abs(gt_drvf(i) - drvf(i)) <= 0.001

print(’Test 10: pass’)

Here is the output of test_10 in the Py shell.

***** Test 10 ************

(((x^2.0)+1.0)*(((x^3.0)+-3.0)*((2.0*(x^1.0))+5.0)))

((((x^2.0)+1.0)*(((x^3.0)+-3.0)*((2.0*(x^1.0))+5.0)))*(((1.0/((x^2.0)+1.0))*((2.0*(x^1.0))+0

(6.0000000000000036, 6.0)

(770.0000000000001, 770.0000000000001)

(5034.0, 5034.0)

(19026.0, 19026.0)

(53894.0, 53894.0)

(127146.0, 127146.0)

(264090.0, 264090.0)

(499273.99999999994, 499274.00000000006)

(877926.0, 877926.0) Test 10: pass

Test 11
Let’s do .

import math from maker import make_prod, make_const, make_pwr, make_e_expr from maker import make_plus, make_quot, make_pwr_expr, make_ln from maker import make_absv from tof import tof from deriv import deriv from deriv import logdiff

def test_11():

print(’\n***** Test 11 ************’) fex1 = make_pwr_expr(make_plus(make_pwr(’x’, 1.0),

make_const(1.0)),

4.0)

fex2 = make_pwr_expr(make_plus(make_prod(make_const(4.0), make_pwr(’x’, 1.0)),

make_const(-1.0)),

2.0)

fex = make_prod(fex1, fex2) print(fex) drv = logdiff(fex) assert not drv is None print(drv) drvf = tof(drv) def gt_drvf(x):

z1 = ((x + 1.0)**4.0) * ((4*x - 1.0)**2.0) z2 = (4.0/(x + 1.0)) + ( 8.0/(4*x - 1.0)) return z1 * z2

for i in range(0, 20):

print(drvf(i), gt_drvf(i)) assert abs(gt_drvf(i) - drvf(i)) <= 0.001

print(’Test 11: pass’) Here is the output of test_11 in the Py shell. ***** Test 11 ************

((((x^1.0)+1.0)^4.0)*(((4.0*(x^1.0))+-1.0)^2.0))

(((((x^1.0)+1.0)^4.0)*(((4.0*(x^1.0))+-1.0)^2.0))*((4.0*((1.0/((x^1.0)+1.0))*((1.0*(x^0.0))+ (-4.0, -4.0)

(671.9999999999999, 671.9999999999999)

(9828.0, 9828.0)

(53504.0, 53504.0)

(187500.00000000003, 187500.00000000003)

(508895.99999999994, 508895.99999999994)

(1167572.0, 1167572.0)

(2377728.0, 2377728.0)

(4429404.0, 4429404.0)

(7700000.0, 7700000.0)

(12665796.000000002, 12665796.000000002) (19913472.0, 19913472.0)

(30151628.000000004, 30151628.000000004)

(44222304.0, 44222304.0)

(63112500.0, 63112500.0)

(87965696.0, 87965696.0)

(120093372.0, 120093372.0)

(160986528.0, 160986528.0)

(212327204.0, 212327204.0)

(276000000.0, 276000000.0) Test 11: pass

More products