-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgl.py
111 lines (81 loc) · 2.43 KB
/
gl.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
import numpy as np
import plotly.express as px
# return the Legendre-Gauss-Lobatto nodes
# N should be the order of polynomial
# thus N1 should be the number of nodes or quads
def lglnodes(N):
N1 = N+1
x = np.cos( np.pi*np.arange(0,N+1)/float(N) )
P = np.zeros((N1,N1))
xold = 2
while np.abs(x-xold).max() > np.finfo(float).eps:
xold = x
P[:,0] = 1
P[:,1] = x
for k in range(2,N+1):
P[:,k] = ((2*k-1)*x*P[:,k-1] - (k-1)*P[:,k-2])/float(k)
x = xold - (x*P[:,N] - P[:,N-1]) / (N1*P[:,N])
w = 2.0/(N*N1*P[:,N]**2)
return (0.5*(x[::-1]+1),0.5*w[::-1])
# form vandermonde matrix using legendre polynomials
def vandermonde(N: int, x: np.array) -> np.array:
N1 = N+1
V = np.zeros((N1,N1))
for i in range(len(x)):
V[i,0] = 1
V[i,1] = x[i]
for k in range(2,N+1):
V[i,k] = ((2*k-1)*x[i]*V[i,k-1] - (k-1)*V[i,k-2])/float(k)
for i in range(len(x)):
for k in range(N+1):
V[i,k] = V[i,k]/np.sqrt(2/(2*k + 1))
return V
# Forms Lagrange interpolating polynomial defined at nodes x1, evaluates the
# polynomial (matrix G) and its derivative (matrix D) at points x2
def lagint(x1, x2):
p1 = len(x1) - 1
p2 = len(x2) - 1
D = np.zeros((p1+1, p1+1))
w = np.ones((p1+1,1))
for j in range(p1+1):
for k in range(p1+1):
if j != k:
w[j] *= x1[j] - x1[k]
w = 1.0/w
for i in range(p1+1):
for j in range(p1+1):
if i != j:
D[i,j] = w[j]/w[i] / (x1[i] - x1[j])
D[i,i] = 0.0
for j in range(p1+1):
if i != j:
D[i,i] -= D[i,j]
G = np.zeros((p2+1, p1+1))
for i in range(p2+1):
ell = 1.0
for j in range(p1+1):
ell *= x2[i] - x1[j]
for j in range(p1+1):
if x2[i] == x1[j]:
G[i,j] = 1
else:
G[i,j] = ell*w[j]/(x2[i] - x1[j])
GD = G.dot(D)
return G, GD
if __name__ == "__main__":
N = 2
lgl = lglnodes(N)
G,D = lagint(lgl[0], lgl[0])
V = vandermonde(N,lgl[0])
vinv = np.linalg.inv(V)
x = np.linspace(0,1,num=N+1)
f = x*x
fq = G@f
fm = vinv@fq
fm[N] = 0
fqt = V@fm
print(fqt)
fig = px.scatter(x=x,y=fq, labels={'x':'x', 'y':'f_q(x0)'} )
fig.show()
fig = px.scatter(x=x,y=V@fqt, labels={'x':'x', 'y':'f_qt(x)'})
fig.show()