7
7
"""
8
8
9
9
import numpy as np
10
- import sys
11
10
from sympy .integrals .quadrature import gauss_gen_laguerre as sp_gauss_laguerre
12
11
import sympy as sp
12
+ from pyfod .utilities import check_function
13
13
14
14
15
15
class GaussLaguerre :
16
16
17
17
def __init__ (self , N = 5 , start = 0.0 , finish = 1.0 , alpha = 0.0 ,
18
18
f = None , extend_precision = True , n_digits = 30 ):
19
19
self .description = 'Gaussian-Laguerre Quadrature'
20
+ self .start = start
21
+ self .finish = finish
22
+ self .alpha = alpha
23
+ self .f = f
20
24
if extend_precision is False :
21
25
points , weights = np .polynomial .laguerre .laggauss (deg = N )
22
26
self .points = 1 - np .exp (- points )
@@ -29,73 +33,100 @@ def __init__(self, N=5, start=0.0, finish=1.0, alpha=0.0,
29
33
np .ones (shape = len (points ))) - points .applyfunc (sp .exp )
30
34
weights = sp .Array (weights )
31
35
self .weights = weights
32
- self .start = start
33
- self .finish = finish
34
- self .alpha = alpha
35
- self .f = f
36
+ self .initial_weights = weights .copy ()
37
+ self .update_weights (alpha = alpha )
36
38
37
- def integrate (self , f = None , alpha = None ):
38
- if alpha is None :
39
- alpha = self .alpha
40
- if f is None :
41
- f = self .f
42
- if f is None :
43
- sys .exit ('No function defined... provide function f' )
39
+ def integrate (self , f = None ):
40
+ f = check_function (f , self .f )
41
+ self .f = f
44
42
# transform kernel
45
43
span = self .finish - self .start
46
44
# check if sympy
47
45
if isinstance (self .points , sp .Array ):
48
46
evalpoints = self .points .applyfunc (
49
47
lambda x : span * x + self .start )
50
48
feval = evalpoints .applyfunc (f )
51
- coef = self .points .applyfunc (
52
- lambda x : span ** (1 - alpha )* (1 - x )** (- alpha ))
53
49
s = 0
54
- for ii , (w , f , t ) in enumerate (zip (self .weights , feval , coef )):
55
- s += w * f * t
50
+ for ii , (w , f ) in enumerate (zip (self .weights , feval )):
51
+ s += w * f
56
52
return s
57
53
else :
58
- coef = span ** (1 - alpha )* (1 - self .points )** (- alpha )
59
- s = (self .weights * (coef * f (span * self .points + self .start ))).sum ()
54
+ s = (self .weights * (f (span * self .points + self .start ))).sum ()
60
55
return s
61
56
57
+ def update_weights (self , alpha = None ):
58
+ if alpha is None :
59
+ alpha = self .alpha
60
+ self .alpha = alpha
61
+ span = self .finish - self .start
62
+ # check if sympy
63
+ if isinstance (self .points , sp .Array ):
64
+ coef = self .points .applyfunc (
65
+ lambda x : span ** (1 - alpha )* (1 - x )** (- alpha ))
66
+ wtmp = []
67
+ for ii , (c , w ) in enumerate (zip (coef , self .initial_weights )):
68
+ wtmp .append (c * w )
69
+ self .weights = sp .Array (wtmp )
70
+ else :
71
+ coef = span ** (1 - alpha )* (1 - self .points )** (- alpha )
72
+ self .weights = self .initial_weights * coef
73
+
62
74
63
75
if __name__ == '__main__' : # pragma: no cover
64
76
65
77
n_digits = 50
66
- alpha = 0.9
67
78
start = 0.0
68
79
finish = 1.0
69
- dt = 1e-6
70
80
N = 24
81
+ '''
82
+ Test normal precision
83
+ '''
84
+ # f(t) = exp(2t)
85
+
86
+ def fexpnp (x ):
87
+ return np .exp (2 * x )
71
88
72
89
def fcosnp (x ):
73
- return np .cos (2 * x ) + 3
90
+ return np .cos (2 * x )
74
91
92
+ # Test alpha = 0.0
93
+ alpha = 0.0
75
94
GLag = GaussLaguerre (N = N , start = start , finish = finish ,
76
- f = fcosnp , alpha = 0 , extend_precision = False )
95
+ f = fexpnp , alpha = alpha , extend_precision = False )
77
96
F1 = GLag .integrate ()
78
- print ('Int(cos(2t)+3) = {} ({})' .format (F1 , 3.4546 ))
97
+ F2 = GLag .integrate (f = fcosnp )
98
+ print ('Int(exp(2t)/(1-t)^{}) = {} ({})' .format (alpha , F1 , 3.19453 ))
99
+ print ('Int(cos(2t)/(1-t)^{}) = {} ({})' .format (alpha , F2 , 0.454649 ))
100
+
101
+ '''
102
+ Test extended precision
103
+ '''
79
104
80
105
def fexp (x ):
81
106
return sp .exp (2 * x )
82
- GLag = GaussLaguerre (N = N , start = start , finish = finish ,
83
- f = fexp , alpha = alpha , n_digits = n_digits )
84
- F1 = GLag .integrate ()
85
- GLag = GaussLaguerre (N = N , start = start , finish = finish - dt ,
86
- f = fexp , alpha = alpha , n_digits = n_digits )
87
- F2 = GLag .integrate ()
88
- print ('D[f(t)=exp(2t)] = {} ({})' .format (
89
- (F1 - F2 )/ (dt * sp .gamma (1 - 0.9 )), 13.815 ))
90
107
91
108
def fcos (x ):
92
109
return sp .cos (2 * x )
93
110
111
+ # Test alpha = 0.0
112
+ alpha = 0.0
94
113
GLag = GaussLaguerre (N = N , start = start , finish = finish ,
95
- f = fcos , alpha = alpha , n_digits = n_digits )
96
- F1 = GLag .integrate ()
97
- GLag = GaussLaguerre (N = N , start = start , finish = finish - dt ,
98
- f = fcos , alpha = alpha , n_digits = n_digits )
99
- F2 = GLag .integrate ()
100
- print ('D[f(t)=cos(2t)] = {} ({})' .format (
101
- (F1 - F2 )/ (dt * sp .gamma (1 - 0.9 )), - 1.779 ))
114
+ alpha = alpha , n_digits = n_digits )
115
+ F1 = GLag .integrate (f = fexp )
116
+ F2 = GLag .integrate (f = fcos )
117
+ print ('Int(exp(2t)/(1-t)^{}) = {} ({})' .format (alpha , F1 , 3.19453 ))
118
+ print ('Int(cos(2t)/(1-t)^{}) = {} ({})' .format (alpha , F2 , 0.454649 ))
119
+ # Test alpha = 0.1
120
+ alpha = 0.1
121
+ GLag .update_weights (alpha = alpha )
122
+ F1 = GLag .integrate (f = fexp )
123
+ F2 = GLag .integrate (f = fcos )
124
+ print ('Int(exp(2t)/(1-t)^{}) = {} ({})' .format (alpha , F1 , 3.749 ))
125
+ print ('Int(cos(2t)/(1-t)^{}) = {} ({})' .format (alpha , F2 , 0.457653 ))
126
+ # Test alpha = 0.9
127
+ alpha = 0.9
128
+ GLag .update_weights (alpha = alpha )
129
+ F1 = GLag .integrate (f = fexp )
130
+ F2 = GLag .integrate (f = fcos )
131
+ print ('Int(exp(2t)/(1-t)^{}) = {} ({})' .format (alpha , F1 , 65.2162 ))
132
+ print ('Int(cos(2t)/(1-t)^{}) = {} ({})' .format (alpha , F2 , - 2.52045 ))
0 commit comments