mathai 2.4.9__tar.gz → 2.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mathai-2.4.9 → mathai-2.5.0}/PKG-INFO +1 -1
- {mathai-2.4.9 → mathai-2.5.0}/mathai/__init__.py +2 -2
- {mathai-2.4.9 → mathai-2.5.0}/mathai/benchmark.py +143 -41
- {mathai-2.4.9 → mathai-2.5.0}/mathai/decision.py +0 -16
- {mathai-2.4.9 → mathai-2.5.0}/mathai/ncert_data.txt +6 -2
- mathai-2.5.0/mathai/ncert_data_optimized.txt +22 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/univariate_inequality.py +1 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai.egg-info/PKG-INFO +1 -1
- {mathai-2.4.9 → mathai-2.5.0}/mathai.egg-info/SOURCES.txt +1 -0
- {mathai-2.4.9 → mathai-2.5.0}/setup.py +2 -2
- {mathai-2.4.9 → mathai-2.5.0}/README.md +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/apart.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/base.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/diff.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/electronic.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/expand.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/factor.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/formula_applier.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/formula_compiler.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/fraction.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/graphics.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/integrate.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/inverse.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/lambda_calculus.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/limit.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/linear.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/logic.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/matrix.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/ml.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/mlscalar.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/ode.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/parser.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/pde.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/printeq.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/qm.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/simplify.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/square_root.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/statistics.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/test.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/tool.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai/trig.py +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/mathai.egg-info/top_level.txt +0 -0
- {mathai-2.4.9 → mathai-2.5.0}/setup.cfg +0 -0
|
@@ -9,7 +9,7 @@ from .graphics import draw_graphics_from_solution, solve_graphics, solve_graphic
|
|
|
9
9
|
|
|
10
10
|
from .square_root import solve_sqrt
|
|
11
11
|
|
|
12
|
-
from .benchmark import benchmark
|
|
12
|
+
from .benchmark import benchmark, god2, benchmark_test
|
|
13
13
|
|
|
14
14
|
from .formula_compiler import formula_compiler
|
|
15
15
|
from .formula_compiler import formula_list_compiler
|
|
@@ -22,7 +22,7 @@ from .linear import linear_solve
|
|
|
22
22
|
|
|
23
23
|
from .test import test
|
|
24
24
|
|
|
25
|
-
from .decision import god
|
|
25
|
+
from .decision import god
|
|
26
26
|
|
|
27
27
|
from .expand import expand
|
|
28
28
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
from pathlib import Path
|
|
3
|
+
import concurrent.futures
|
|
3
4
|
|
|
4
5
|
from .simplify import simplify
|
|
5
6
|
from .expand import expand
|
|
@@ -20,9 +21,16 @@ from .limit import limit1
|
|
|
20
21
|
from .logic import logic0
|
|
21
22
|
from .base import *
|
|
22
23
|
|
|
24
|
+
def _no_integrate_left(eq):
|
|
25
|
+
return eq.name == "f_range" or eq.name == "s_true" or all(not contain2(eq, "f_"+item) for item in "eq integrate subs limit limitpinf limitninf".split(" "))
|
|
26
|
+
|
|
27
|
+
# Top-level helper function for picklability in multiprocessing
|
|
28
|
+
def run_absolute(x):
|
|
29
|
+
return dowhile(x, absolute)
|
|
30
|
+
|
|
23
31
|
|
|
24
32
|
fx_list = [
|
|
25
|
-
|
|
33
|
+
run_absolute,
|
|
26
34
|
logic0,
|
|
27
35
|
limit1,
|
|
28
36
|
simple_wavycurvy,
|
|
@@ -52,45 +60,6 @@ integrate_clean apart trig0 trig1 trig4 integrate_fraction factor2 trig6
|
|
|
52
60
|
FUNCS = dict(zip(name_list, fx_list))
|
|
53
61
|
|
|
54
62
|
|
|
55
|
-
# ---------------------------------------------------------------------------
|
|
56
|
-
# Benchmark
|
|
57
|
-
# ---------------------------------------------------------------------------
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def benchmark(s="ncert_data"):
|
|
61
|
-
data_path = Path(__file__).parent / f"{s}.txt"
|
|
62
|
-
output_path = Path(__file__).parent / f"{s}_optimized.txt"
|
|
63
|
-
|
|
64
|
-
optimized_lines = []
|
|
65
|
-
|
|
66
|
-
with open(data_path, "r", encoding="utf-8") as file:
|
|
67
|
-
for count, line in enumerate(file, 1):
|
|
68
|
-
parts = line.split()
|
|
69
|
-
|
|
70
|
-
if not parts:
|
|
71
|
-
continue
|
|
72
|
-
|
|
73
|
-
expr_str, *function_names = parts
|
|
74
|
-
eq = simplify(parse(expr_str))
|
|
75
|
-
effective_steps = [expr_str]
|
|
76
|
-
|
|
77
|
-
for func_name in function_names:
|
|
78
|
-
func = FUNCS[func_name]
|
|
79
|
-
prev_eq = copy.deepcopy(eq)
|
|
80
|
-
eq = func(eq)
|
|
81
|
-
|
|
82
|
-
if eq != prev_eq:
|
|
83
|
-
effective_steps.append(func_name)
|
|
84
|
-
|
|
85
|
-
print(f"{count}. {expr_str} => {eq}")
|
|
86
|
-
optimized_lines.append(" ".join(effective_steps))
|
|
87
|
-
|
|
88
|
-
with open(output_path, "w", encoding="utf-8") as file:
|
|
89
|
-
file.write("\n".join(optimized_lines) + "\n")
|
|
90
|
-
|
|
91
|
-
print(f"\nOptimized dataset successfully written to: {output_path}")
|
|
92
|
-
|
|
93
|
-
|
|
94
63
|
# ---------------------------------------------------------------------------
|
|
95
64
|
# Strategy tree
|
|
96
65
|
# ---------------------------------------------------------------------------
|
|
@@ -173,7 +142,7 @@ def print_tree(node, depth=0):
|
|
|
173
142
|
|
|
174
143
|
|
|
175
144
|
# ---------------------------------------------------------------------------
|
|
176
|
-
# Serial Execution Entry
|
|
145
|
+
# Serial & Parallel Execution Entry Points
|
|
177
146
|
# ---------------------------------------------------------------------------
|
|
178
147
|
|
|
179
148
|
|
|
@@ -193,3 +162,136 @@ def execute_serial(tree, equation, terminal_condition=None):
|
|
|
193
162
|
return [(eq, seq)]
|
|
194
163
|
|
|
195
164
|
return []
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _execute_child_worker(args):
|
|
168
|
+
"""Worker helper function for parallel execution across cores."""
|
|
169
|
+
child, equation, terminal_condition = args
|
|
170
|
+
try:
|
|
171
|
+
return child.execute(copy.deepcopy(equation), [], terminal_condition)
|
|
172
|
+
except Exception:
|
|
173
|
+
return []
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def execute_parallel(tree, equation, terminal_condition=None):
|
|
177
|
+
"""
|
|
178
|
+
Splits the strategy tree root node's children and distributes
|
|
179
|
+
them across multiple CPU cores using ProcessPoolExecutor.
|
|
180
|
+
"""
|
|
181
|
+
children = list(tree.children.values())
|
|
182
|
+
if not children:
|
|
183
|
+
return []
|
|
184
|
+
|
|
185
|
+
tasks = [(child, equation, terminal_condition) for child in children]
|
|
186
|
+
|
|
187
|
+
with concurrent.futures.ProcessPoolExecutor() as executor:
|
|
188
|
+
futures = [executor.submit(_execute_child_worker, task) for task in tasks]
|
|
189
|
+
|
|
190
|
+
for future in concurrent.futures.as_completed(futures):
|
|
191
|
+
try:
|
|
192
|
+
results = future.result()
|
|
193
|
+
for eq, seq in results:
|
|
194
|
+
if terminal_condition is None or terminal_condition(eq):
|
|
195
|
+
return [(eq, seq)]
|
|
196
|
+
except Exception:
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
return []
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def god2(string, parallel=False):
|
|
203
|
+
tree = strategy_tree(load_sequences("ncert_data"))
|
|
204
|
+
if parallel:
|
|
205
|
+
out = execute_parallel(tree, simplify(parse(string)), _no_integrate_left)
|
|
206
|
+
else:
|
|
207
|
+
out = execute_serial(tree, simplify(parse(string)), _no_integrate_left)
|
|
208
|
+
if len(out) >= 1:
|
|
209
|
+
print(string)
|
|
210
|
+
print("=>", out[0][0])
|
|
211
|
+
print(["parse", "simplify"] + out[0][1])
|
|
212
|
+
return out
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# ---------------------------------------------------------------------------
|
|
216
|
+
# Benchmark Test (Pure Execution, No Writing, No Strategy Trees)
|
|
217
|
+
# ---------------------------------------------------------------------------
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def benchmark_test(s="ncert_data"):
|
|
221
|
+
data_path = Path(__file__).parent / f"{s}.txt"
|
|
222
|
+
|
|
223
|
+
with open(data_path, "r", encoding="utf-8") as file:
|
|
224
|
+
for count, line in enumerate(file, 1):
|
|
225
|
+
parts = line.split()
|
|
226
|
+
|
|
227
|
+
if not parts:
|
|
228
|
+
continue
|
|
229
|
+
|
|
230
|
+
expr_str, *function_names = parts
|
|
231
|
+
eq = simplify(parse(expr_str))
|
|
232
|
+
|
|
233
|
+
for func_name in function_names:
|
|
234
|
+
func = FUNCS[func_name]
|
|
235
|
+
prev_eq = copy.deepcopy(eq)
|
|
236
|
+
eq = func(eq)
|
|
237
|
+
|
|
238
|
+
print(f"{count}. {expr_str} => {eq}")
|
|
239
|
+
|
|
240
|
+
print(f"\nBenchmark test execution completed for: {s}.txt")
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
# ---------------------------------------------------------------------------
|
|
244
|
+
# Benchmark
|
|
245
|
+
# ---------------------------------------------------------------------------
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def benchmark(s="ncert_data"):
|
|
249
|
+
data_path = Path(__file__).parent / f"{s}.txt"
|
|
250
|
+
output_path = Path(__file__).parent / f"{s}_optimized.txt"
|
|
251
|
+
|
|
252
|
+
optimized_lines = []
|
|
253
|
+
|
|
254
|
+
# Initialize an empty strategy tree
|
|
255
|
+
tree = Node("ROOT")
|
|
256
|
+
|
|
257
|
+
with open(data_path, "r", encoding="utf-8") as file:
|
|
258
|
+
for count, line in enumerate(file, 1):
|
|
259
|
+
parts = line.split()
|
|
260
|
+
|
|
261
|
+
if not parts:
|
|
262
|
+
continue
|
|
263
|
+
|
|
264
|
+
expr_str, *function_names = parts
|
|
265
|
+
eq_parsed = simplify(parse(expr_str))
|
|
266
|
+
|
|
267
|
+
# Try solving with the strategy tree built so far
|
|
268
|
+
out = execute_serial(tree, eq_parsed, _no_integrate_left)
|
|
269
|
+
|
|
270
|
+
if len(out) >= 1:
|
|
271
|
+
# Solved successfully by the strategy tree: DO NOT update tree, exclude from optimized file
|
|
272
|
+
print(f"{count}.", expr_str, "=>", out[0][0])
|
|
273
|
+
continue
|
|
274
|
+
|
|
275
|
+
# Strategy tree failed: fall back to manual function sequence
|
|
276
|
+
eq = eq_parsed
|
|
277
|
+
effective_steps = [expr_str]
|
|
278
|
+
|
|
279
|
+
for func_name in function_names:
|
|
280
|
+
func = FUNCS[func_name]
|
|
281
|
+
prev_eq = copy.deepcopy(eq)
|
|
282
|
+
eq = func(eq)
|
|
283
|
+
if eq != prev_eq:
|
|
284
|
+
effective_steps.append(func_name)
|
|
285
|
+
|
|
286
|
+
# Update the strategy tree ONLY because it failed
|
|
287
|
+
current_node = tree
|
|
288
|
+
for func_name in effective_steps[1:]:
|
|
289
|
+
current_node = current_node.add_child(func_name)
|
|
290
|
+
|
|
291
|
+
print(f"{count}. {expr_str} => {eq} **")
|
|
292
|
+
optimized_lines.append(" ".join(effective_steps))
|
|
293
|
+
|
|
294
|
+
with open(output_path, "w", encoding="utf-8") as file:
|
|
295
|
+
file.write("\n".join(optimized_lines) + "\n")
|
|
296
|
+
|
|
297
|
+
print(f"\nOptimized dataset successfully written to: {output_path}")
|
|
@@ -15,7 +15,6 @@ from .factor import factor2, factor
|
|
|
15
15
|
from .limit import limit1, limit5
|
|
16
16
|
from .linear import linear_solve
|
|
17
17
|
from .matrix import matrix_solve, matrix_formula
|
|
18
|
-
from .benchmark import load_sequences, strategy_tree, execute_serial
|
|
19
18
|
|
|
20
19
|
def vlist_2(eq):
|
|
21
20
|
out = []
|
|
@@ -61,21 +60,6 @@ def solve_subs(q):
|
|
|
61
60
|
if len(solution.keys()) == 0:
|
|
62
61
|
return orig
|
|
63
62
|
return operation("f_and", [item for item in lst if all(not contain(item, tree_form(key)) for key in solution.keys())] + [TreeNode("f_eq", [tree_form(key), item]) for key, item in solution.items()])
|
|
64
|
-
def _no_integrate_left(eq):
|
|
65
|
-
return eq.name == "f_range" or eq.name == "s_true" or all(not contain2(eq, "f_"+item) for item in "eq integrate subs limit limitpinf limitninf".split(" "))
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def god2(string):
|
|
69
|
-
out = execute_serial(
|
|
70
|
-
strategy_tree(load_sequences("ncert_data")),
|
|
71
|
-
simplify(parse(string)),
|
|
72
|
-
_no_integrate_left,
|
|
73
|
-
)
|
|
74
|
-
if len(out) >= 1:
|
|
75
|
-
print(string)
|
|
76
|
-
print("=>", out[0][0])
|
|
77
|
-
print(["parse", "simplify"] + out[0][1])
|
|
78
|
-
return None
|
|
79
63
|
|
|
80
64
|
def god(string, debug=True):
|
|
81
65
|
if debug:
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
(
|
|
1
|
+
(x+1)*(x-1)=x^2-1 expand simplify logic0
|
|
2
|
+
(a+b)^2=a^2+b^2+2*a*b expand simplify logic0
|
|
3
|
+
1+1=2 logic0
|
|
4
|
+
sin(x)^2+cos(x)^2=1 trig1 simplify logic0
|
|
3
5
|
(1/(1-4*i)-2/(1+i))*((3-4*i)/(5+i))
|
|
4
6
|
limit((1-cos(x))/x,x) limit1
|
|
5
7
|
limit(sin(4*x)/sin(2*x),x) limit1
|
|
@@ -62,3 +64,5 @@ integrate(log(x)^2/x,x) integrate_subs integrate_formula integrate_clean
|
|
|
62
64
|
integrate(sin(arctan(x))/(1+x^2),x) integrate_subs integrate_formula integrate_clean
|
|
63
65
|
integrate(2*x*sin(x^2+1),x) integrate_formula integrate_subs integrate_formula integrate_clean
|
|
64
66
|
integrate(sin(m*x),x) integrate_formula
|
|
67
|
+
abs(3*x-5)+abs(8-x)=abs(3+2*x) absolute simplify simple_wavycurvy
|
|
68
|
+
(sin(x)+cosec(x))^2+(cos(x)+sec(x))^2=7+tan(x)^2+cot(x)^2 trig0 fraction trig1 fraction simplify trig1 logic0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(x+1)*(x-1)=x^2-1 expand simplify logic0
|
|
2
|
+
1+1=2 logic0
|
|
3
|
+
sin(x)^2+cos(x)^2=1 trig1 logic0
|
|
4
|
+
(1/(1-4*i)-2/(1+i))*((3-4*i)/(5+i))
|
|
5
|
+
limit((1-cos(x))/x,x) limit1
|
|
6
|
+
4*x+3<6*x+7 simple_wavycurvy
|
|
7
|
+
integrate(x/((x+1)*(x+2)),x) apart integrate_formula
|
|
8
|
+
integrate(sin(2*x+5)^2,x) trig1 integrate_formula
|
|
9
|
+
integrate((1-cos(x))/(1+cos(x)),x) trig6 expand integrate_formula integrate_trig_formula simplify integrate_trig_formula integrate_formula
|
|
10
|
+
integrate(sin(x)/(1+cos(x)),x) trig6 expand integrate_formula simplify integrate_trig_formula
|
|
11
|
+
integrate(cos(2*x),x) integrate_formula
|
|
12
|
+
integrate(cosec(x)*(cosec(x)+cot(x)),x) trig0 fraction expand integrate_formula simplify integrate_trig_formula
|
|
13
|
+
integrate((1-sin(x))/cos(x)^2,x) expand integrate_formula integrate_trig_formula
|
|
14
|
+
integrate(x^2*(1-1/x^2),x) expand simplify integrate_formula
|
|
15
|
+
integrate(sec(x)^2/cosec(x)^2,x) trig0 simplify integrate_trig_formula integrate_formula trig1
|
|
16
|
+
integrate(sin(x)/sin(x+a),x) integrate_subs expand simplify integrate_formula integrate_trig_formula integrate_clean
|
|
17
|
+
integrate((e^(2*x)-1)/(e^(2*x)+1),x) integrate_subs integrate_formula expand simplify apart integrate_formula integrate_clean
|
|
18
|
+
integrate((e^(2*x)-e^(-2*x))/(e^(2*x)+e^(-2*x)),x) integrate_subs integrate_formula fraction simplify apart integrate_formula integrate_fraction integrate_clean
|
|
19
|
+
integrate(tan(2*x-3)^2,x) trig0 integrate_trig_formula integrate_formula
|
|
20
|
+
integrate((4*x+2)*sqrt(x^2+x+1),x) integrate_subs integrate_formula integrate_clean
|
|
21
|
+
abs(3*x-5)+abs(8-x)=abs(3+2*x) absolute simplify simple_wavycurvy
|
|
22
|
+
(sin(x)+cosec(x))^2+(cos(x)+sec(x))^2=7+tan(x)^2+cot(x)^2 trig0 fraction trig1 fraction simplify trig1 logic0
|
|
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|
|
3
3
|
|
|
4
4
|
setup(
|
|
5
5
|
name="mathai",
|
|
6
|
-
version="2.
|
|
6
|
+
version="2.5.0",
|
|
7
7
|
description="Mathematics solving Ai tailored to NCERT",
|
|
8
8
|
long_description=Path("README.md").read_text(encoding="utf-8"),
|
|
9
9
|
long_description_content_type="text/markdown",
|
|
@@ -11,7 +11,7 @@ setup(
|
|
|
11
11
|
packages=find_packages(),
|
|
12
12
|
include_package_data=True,
|
|
13
13
|
package_data={
|
|
14
|
-
"mathai": ["ncert_data.txt"],
|
|
14
|
+
"mathai": ["ncert_data.txt", "ncert_data_optimized.txt"],
|
|
15
15
|
},
|
|
16
16
|
python_requires=">=3.7",
|
|
17
17
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|