forked from spyder-ide/spyder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinitediffdiffeq.py
133 lines (91 loc) · 4.07 KB
/
finitediffdiffeq.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# -*- coding: utf-8 -*-
"""
Created on Fri Jan 15 16:03:05 2021
@author: MarlaJahari
"""
import numpy as np
import matplotlib.pyplot as ourplot
"PROBLEM: To solve the given diff eqn using finite difference method"
"y2=y'+x(x-4) p(x)=1 q(x)=0 r(x)=x(x-4) 0<x<4 y(0)=y(4)=0"
'[a,b]=[0,4]'
a=0 #upper limit
b=4 #lower limit
n=int(input('no of steps YOU WISH'))
h=(b-a)/n
p=1 #co-efficient of first derivative
q=0 #co-efficient of y
'(2-p*h)y[i+1]+ (-4)y[i] + (2+p*h)y[i-1]=2rh^2 (substituting our equation in FDM)'
c=[] #vector to store the constants on right
for i in range(1,n,1):
r=2*i*h*((i*h)-4)#since x=0+i*h
C= r*h**2 #the constant part of equation
c.append(C) #producing elements in loop and adding them to c
A=-4 #(-2*q*h**2-4) co-efficient of y[i] throughout the loop
B=2-p*h #co-efficient of y[i+1] "
E=2+p*h #co-efficient of y[i-1] "
x=[] #for storing A for diff values of i
y=[] #for storing B for "
z=[] #for storing E for "
for i in range(n-1):
x.append(A) #adding B to vector x for diff i's
for i in range(n-2):
y.append(B) #adding A to vector y for diff i's
z.append(E)
def tridiag(x,y,z, k1=-1,k2=0,k3=1): #creating a function for triD matrix
return np.diag(x,k2) + np.diag(z,k1)+ np.diag(y,k3) #main+off+off
M=tridiag(x, y, z) #built matrix
P=np.array([[c]]).T #converting const array to soln column vector
print("Our co-efficient matrix:")
print(M) #printing matrix (*not printed with the command for spacing)
print("Our constant matrix:")
print(P) #printing soln vector
'Algorithm for Thomas method to solve tri-diagonal matrixes'
"""
here consider our reference matrix is of form
[b1 c1 0
a2 b2 c2
0 a3 b2]
"""
v=len(c) #extracting the length of const mtrx
f=np.zeros(v-1) #creating an array of zeros length v-1
g=np.zeros(v)
d=np.zeros(v)
'~Matrix Operations~'
# for an eq b1x1+ c1x2=r1, div throughout by b1(1st element of main D)>>
f[0]=y[0]/x[0] #dividing 1st elm(Up-D) by 1st elm(M-D)
g[0]=c[0]/x[0]
#row2- eqn a2x1+b2x2+c2x3, to eliminate a2x1>>
#take the 1st element of off-D below(a2) and multiply by the 1st row
#repeat it down the rows until all the MD elms=1, lD elms=0, uD elms=k
#we divide throughout by b2-a2*(k) k=previous uD modified elm>>
for i in range(1,v-1):
f[i]=y[i]/(x[i]-z[i-1]*f[i-1]) #co-efficients of xi throughout
for i in range(1,v):
#now we modify const Vectr in sync with the rest of our operations
#modifying constant Vectr>> c1=r1/b1, c2=(r2-a2r1)/(b2-a2k1),c3=..etc
g[i]=(c[i]-z[i-1]*g[i-1])/(x[i]-z[i-1]*f[i-1])
#equating modified const vector w/ final soln vector
d[v-1]=g[v-1]
#d stores the final solution for each elm simultaneously by backward subst
'Final Backward Substitution'
for i in range(v-1,0,-1):
d[i-1]=g[i-1]-f[i-1]*d[i] #backw subst (x1=r1-x2*k1, x2=r2-""..)
T=d #soln by Thomas' algorithm
W=np.linalg.solve(M,c) #soln by in-built funcn
print("The solution vector by inbuilt numpy func: ",W)
print("The solution vector by Thomas' Algorithm:",d)
'PLOTTING'
#for plotting Y, we create a zero vectr w/ soln values in between
Y=np.zeros(n+1)
for i in range(1,n):
Y[i]=d[i-1]
#for plotting X, we create a vector to store subsequent values in a loop
X=[]
for i in range(n+1):
x=i*h
X.append(x)
ourplot.title("FINITE DIFFERENCE GRAPH")
ourplot.xlabel("X")
ourplot.ylabel("Plotting discrete y-values")
ourplot.plot(X,Y)
ourplot.show()