1
- from math import *
1
+ import numpy as np
2
+ from sympy import lambdify , symbols , sympify
2
3
3
4
4
5
def get_inputs ():
5
6
"""
6
7
Get user input for the function, lower limit, and upper limit.
7
8
8
9
Returns:
9
- tuple: A tuple containing the function as a string, the lower limit (a), and the upper limit (b) as floats.
10
+ tuple: A tuple containing the function as a string, the lower limit (a),
11
+ and the upper limit (b) as floats.
10
12
11
13
Example:
12
14
>>> from unittest.mock import patch
@@ -21,6 +23,24 @@ def get_inputs():
21
23
return func , a , b
22
24
23
25
26
+ def safe_function_eval (func_str ):
27
+ """
28
+ Safely evaluates the function by substituting x value using sympy.
29
+
30
+ Args:
31
+ func_str (str): Function expression as a string.
32
+
33
+ Returns:
34
+ float: The evaluated function result.
35
+ """
36
+ x = symbols ('x' )
37
+ func_expr = sympify (func_str )
38
+
39
+ # Convert the function to a callable lambda function
40
+ lambda_func = lambdify (x , func_expr , modules = ["numpy" ])
41
+ return lambda_func
42
+
43
+
24
44
def compute_table (func , a , b , acc ):
25
45
"""
26
46
Compute the table of function values based on the limits and accuracy.
@@ -35,14 +55,19 @@ def compute_table(func, a, b, acc):
35
55
tuple: A tuple containing the table of values and the step size (h).
36
56
37
57
Example:
38
- >>> compute_table('1/(1+x**2)', 1, -1, 1)
39
- ([0.5, 0.4235294117647058, 0.36, 0.3076923076923077, 0.26470588235294124, 0.22929936305732482, 0.2], -0.3333333333333333)
58
+ >>> compute_table(
59
+ ... safe_function_eval('1/(1+x**2)'), 1, -1, 1
60
+ ... )
61
+ (array([0.5 , 0.69230769, 0.9 , 1. , 0.9 ,
62
+ 0.69230769, 0.5 ]), -0.3333333333333333)
40
63
"""
41
- h = (b - a ) / (acc * 6 )
42
- table = [0 for _ in range (acc * 6 + 1 )]
43
- for j in range (acc * 6 + 1 ):
44
- x = a + j / (acc * 6 )
45
- table [j ] = eval (func )
64
+ # Weddle's rule requires number of intervals as a multiple of 6 for accuracy
65
+ n_points = acc * 6 + 1
66
+ h = (b - a ) / (n_points - 1 )
67
+ x_vals = np .linspace (a , b , n_points )
68
+
69
+ # Evaluate function values at all points
70
+ table = func (x_vals )
46
71
return table , h
47
72
48
73
@@ -86,25 +111,25 @@ def compute_solution(add, table, h):
86
111
float: The final computed integral solution.
87
112
88
113
Example:
89
- >>> compute_solution([4.33, 6.0, 0.0, -4.33], [0.0, 0.866, 1.0, 0.866, 0.0, -0.866, -1.0], 0.5235983333333333)
114
+ >>> compute_solution([4.33, 6.0, 0.0, -4.33], [0.0, 0.866, 1.0, 0.866, 0.0,
115
+ ... -0.866, -1.0], 0.5235983333333333)
90
116
0.7853975
91
117
"""
92
118
return 0.3 * h * (sum (add ) + table [0 ] + table [- 1 ])
93
119
94
120
95
121
if __name__ == "__main__" :
96
122
from doctest import testmod
97
-
98
123
testmod ()
99
-
124
+
100
125
func , a , b = get_inputs ()
101
126
acc = 1
102
127
solution = None
103
128
104
- while acc <= 100000 :
129
+ while acc <= 100_000 :
105
130
table , h = compute_table (func , a , b , acc )
106
131
add = apply_weights (table )
107
132
solution = compute_solution (add , table , h )
108
133
acc *= 10
109
134
110
- print (f" Solution: { solution } " )
135
+ print (f' Solution: { solution } ' )
0 commit comments