-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdifferentiation.py
112 lines (91 loc) · 3.98 KB
/
differentiation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from logging import exception
import numpy as np
def input_data():
data_x = np.array([])
data_y = np.array([])
n = int(input("Enter the number of points: "))
for i in range(n):
data_x = np.append(data_x, float(input("X[{}]: ".format(i))))
for i in range(n):
data_y = np.append(data_y, float(input("Y[{}]: ".format(i))))
x = float(input("Find dY/dX for X = "))
return [data_x, data_y, x]
def forward_difference_first_order(data_x, data_y, x):
if x == data_x[-1]:
raise Exception("The derivative of the last point can't be obtained using forward difference")
idx = np.where(data_x == x)
if idx[0].size == 0:
raise Exception("The X point isn't in the given data")
else:
return (data_y[idx[0][0] + 1] - data_y[idx[0][0]])/(data_x[idx[0][0] + 1] - data_x[idx[0][0]])
def forward_difference_second_order(data_x, data_y, x):
if x == data_x[-1] or x == data_x[-2]:
raise Exception("The derivative of the last two points can't be obtained using forward difference")
dx = data_x[1] - data_x[0]
for i in range(2, data_x.size):
# Allowed error is 1e-4
if abs(data_x[i] - data_x[i - 1] - dx) > 1e-4:
raise Exception("All the points should be equally spaced")
idx = np.where(data_x == x)
if idx[0].size == 0:
raise Exception("The X point isn't in the given data")
else:
return (data_y[idx[0][0] + 2] - 2 * data_y[idx[0][0] + 1] + data_y[idx[0][0]])/(dx * dx)
def backward_difference_first_order(data_x, data_y, x):
if x == data_x[0]:
raise Exception("The derivative of the first point can't be obtained using backward difference")
idx = np.where(data_x == x)
if idx[0].size == 0:
raise Exception("The X point isn't in the given data")
else:
return (data_y[idx[0][0]] - data_y[idx[0][0] - 1])/(data_x[idx[0][0]] - data_x[idx[0][0] - 1])
def centered_difference_first_order(data_x, data_y, x):
if x == data_x[0] or x == data_x[-1]:
raise Exception("The derivative of the first and last point can't be obtained using centered difference")
idx = np.where(data_x == x)
if idx[0].size == 0:
raise Exception("The X point isn't in the given data")
else:
return (data_y[idx[0][0] + 1] - data_y[idx[0][0] - 1])/(2 * (data_x[idx[0][0]] - data_x[idx[0][0] - 1]))
def centered_difference_second_order(data_x, data_y, x):
if x == data_x[-1] or x == data_x[0]:
raise Exception("The derivative of the last two points can't be obtained using forward difference")
dx = data_x[1] - data_x[0]
for i in range(2, data_x.size):
# Allowed error is 1e-4
if abs(data_x[i] - data_x[i - 1] - dx) > 1e-4:
raise Exception("All the points should be equally spaced")
idx = np.where(data_x == x)
if idx[0].size == 0:
raise Exception("The X point isn't in the given data")
else:
return (data_y[idx[0][0] + 1] + data_y[idx[0][0] - 1] - 2*data_y[idx[0][0]])/(dx * dx)
def test_forward_difference():
data_x, data_y, x = input_data()
dy = forward_difference_first_order(data_x, data_y, x)
print("dY/dX at X = {} : {}".format(x, dy))
dy2 = forward_difference_second_order(data_x, data_y, x)
print("d2Y/dX2 at X = {} : {}".format(x, dy2))
def test_backward_difference():
"""
Example:
X = 1, 2, 4
Y = 1.1, 0.7, 0.4
dY/dX at X = 2 : -0.4
"""
data_x, data_y, x = input_data()
dy = backward_difference_first_order(data_x, data_y, x)
print("dY/dX at X = {} : {}".format(x, dy))
def test_centered_difference():
"""
Example:
X = 1.0, 1.2, 1.4, 1.6
Y = 1.359, 1.660, 2.028, 2.477
dY/dX at X = 1.4 : 2.043
d2Y/dX2 at X = 1.4 : 2.025
"""
data_x, data_y, x = input_data()
dy = centered_difference_first_order(data_x, data_y, x)
print("dY/dX at X = {} : {}".format(x, dy))
dy2 = centered_difference_second_order(data_x, data_y, x)
print("d2Y/dX2 at X = {} : {}".format(x, dy2))