mathai 0.4.6__tar.gz → 0.4.8__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-0.4.6 → mathai-0.4.8}/PKG-INFO +4 -1
- {mathai-0.4.6 → mathai-0.4.8}/README.md +3 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/__init__.py +5 -2
- {mathai-0.4.6 → mathai-0.4.8}/mathai/apart.py +28 -9
- {mathai-0.4.6 → mathai-0.4.8}/mathai/base.py +1 -1
- {mathai-0.4.6 → mathai-0.4.8}/mathai/factor.py +93 -33
- {mathai-0.4.6 → mathai-0.4.8}/mathai/integrate.py +39 -5
- {mathai-0.4.6 → mathai-0.4.8}/mathai/limit.py +2 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/simplify.py +12 -1
- mathai-0.4.8/mathai/tool.py +163 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/trig.py +58 -47
- {mathai-0.4.6 → mathai-0.4.8}/mathai.egg-info/PKG-INFO +4 -1
- {mathai-0.4.6 → mathai-0.4.8}/setup.py +1 -1
- mathai-0.4.6/mathai/tool.py +0 -62
- {mathai-0.4.6 → mathai-0.4.8}/mathai/console.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/diff.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/expand.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/fraction.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/inverse.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/linear.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/logic.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/ode.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/parser.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/printeq.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/structure.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai/univariate_inequality.py +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai.egg-info/SOURCES.txt +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai.egg-info/requires.txt +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/mathai.egg-info/top_level.txt +0 -0
- {mathai-0.4.6 → mathai-0.4.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathai
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.8
|
|
4
4
|
Summary: Mathematics solving Ai tailored to NCERT
|
|
5
5
|
Home-page: https://github.com/infinity390/mathai4
|
|
6
6
|
Author: educated indians are having a low iq and are good for nothing
|
|
@@ -16,6 +16,9 @@ Dynamic: requires-python
|
|
|
16
16
|
Dynamic: summary
|
|
17
17
|
|
|
18
18
|
# Math AI Documentation
|
|
19
|
+
## Source
|
|
20
|
+
Github repository of the code
|
|
21
|
+
https://github.com/infinity390/mathai4
|
|
19
22
|
|
|
20
23
|
## Philosophy
|
|
21
24
|
I think it is a big realization in computer science and programming to realize that computers can solve mathematics.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from .ode import diffsolve as ode_solve
|
|
2
2
|
from .ode import diffsolve_sep as ode_shift_term
|
|
3
3
|
|
|
4
|
+
from .linear import linear_solve
|
|
5
|
+
|
|
4
6
|
from .expand import expand
|
|
5
7
|
|
|
6
8
|
from .parser import parse
|
|
@@ -35,7 +37,7 @@ from .trig import trig0, trig1, trig2, trig3, trig4
|
|
|
35
37
|
|
|
36
38
|
from .logic import logic0, logic1, logic2, logic3
|
|
37
39
|
|
|
38
|
-
from .apart import apart
|
|
40
|
+
from .apart import apart, apart2
|
|
39
41
|
|
|
40
42
|
from .console import console
|
|
41
43
|
|
|
@@ -46,4 +48,5 @@ from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
|
|
|
46
48
|
from .base import *
|
|
47
49
|
|
|
48
50
|
from .tool import enclose_const
|
|
49
|
-
|
|
51
|
+
from .tool import poly_simplify
|
|
52
|
+
from .tool import longdiv
|
|
@@ -6,19 +6,23 @@ from .diff import diff
|
|
|
6
6
|
from .inverse import inverse
|
|
7
7
|
from .base import *
|
|
8
8
|
import math
|
|
9
|
-
from .
|
|
9
|
+
from .factor import factor2
|
|
10
|
+
from .tool import poly, enclose_const, longdiv
|
|
10
11
|
|
|
11
12
|
def _apart(eq, v=None):
|
|
13
|
+
|
|
12
14
|
if v is None:
|
|
13
15
|
if len(vlist(eq)) == 0:
|
|
14
16
|
return eq
|
|
15
17
|
v = vlist(eq)[0]
|
|
16
18
|
origv = vlist(eq)
|
|
17
|
-
|
|
19
|
+
|
|
18
20
|
if eq.name != "f_mul":
|
|
19
21
|
return eq
|
|
22
|
+
|
|
20
23
|
if any("f_"+item in str_form(eq) for item in "sin cos tan log".split(" ")):
|
|
21
24
|
return eq
|
|
25
|
+
|
|
22
26
|
def exclude(eq):
|
|
23
27
|
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator != 1:
|
|
24
28
|
return False
|
|
@@ -48,7 +52,7 @@ def _apart(eq, v=None):
|
|
|
48
52
|
|
|
49
53
|
|
|
50
54
|
facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(expand(simplify(m-n))) == tree_form("d_0"))
|
|
51
|
-
|
|
55
|
+
|
|
52
56
|
if len(facd2) == 1:
|
|
53
57
|
return eq
|
|
54
58
|
x = tree_form(v)
|
|
@@ -60,7 +64,7 @@ def _apart(eq, v=None):
|
|
|
60
64
|
g = countfac(facd, item)
|
|
61
65
|
for n in range(int(g.name[2:])):
|
|
62
66
|
n = n+1
|
|
63
|
-
if n >
|
|
67
|
+
if n > 3:
|
|
64
68
|
return eq
|
|
65
69
|
n = tree_form("d_"+str(n))
|
|
66
70
|
|
|
@@ -87,6 +91,7 @@ def _apart(eq, v=None):
|
|
|
87
91
|
dem.append(item**n)
|
|
88
92
|
s.append(a/item**n)
|
|
89
93
|
else:
|
|
94
|
+
|
|
90
95
|
return eq
|
|
91
96
|
final3 = summation(s)
|
|
92
97
|
|
|
@@ -95,13 +100,13 @@ def _apart(eq, v=None):
|
|
|
95
100
|
final2 = []
|
|
96
101
|
for i in range(len(num)):
|
|
97
102
|
final2.append(product([dem[k] for k in range(len(dem)) if i != k])*num[i])
|
|
98
|
-
|
|
103
|
+
|
|
99
104
|
final = summation(final2)
|
|
100
|
-
|
|
105
|
+
|
|
101
106
|
s = simplify(TreeNode("f_eq", [final-eq2, tree_form("d_0")]))
|
|
102
|
-
|
|
107
|
+
|
|
103
108
|
lst = poly(s.children[0], v)
|
|
104
|
-
|
|
109
|
+
|
|
105
110
|
lst = [TreeNode("f_eq", [item, tree_form("d_0")]) for item in lst if "v_" in str_form(item)]
|
|
106
111
|
lst2 = []
|
|
107
112
|
for item in lst:
|
|
@@ -112,12 +117,26 @@ def _apart(eq, v=None):
|
|
|
112
117
|
for item in out.children:
|
|
113
118
|
|
|
114
119
|
final3 = replace(final3, tree_form(list(set(vlist(item))&set(origv))[0]), inverse(item.children[0], list(set(vlist(item))&set(origv))[0]))
|
|
115
|
-
|
|
120
|
+
final4 = simplify(final3)
|
|
121
|
+
|
|
122
|
+
return final4
|
|
123
|
+
def apart2(eq):
|
|
124
|
+
if eq.name == "f_mul":
|
|
125
|
+
|
|
126
|
+
a, b = num_dem(eq)
|
|
127
|
+
|
|
128
|
+
tmp = longdiv(a, b, 2, 1)
|
|
129
|
+
|
|
130
|
+
if tmp is not None:
|
|
131
|
+
return simplify(tmp[0]+tmp[1]/b)
|
|
132
|
+
return TreeNode(eq.name, [apart2(child) for child in eq.children])
|
|
116
133
|
def apart(eq):
|
|
134
|
+
eq = factor2(simplify(eq))
|
|
117
135
|
eq, fx = enclose_const(eq)
|
|
118
136
|
def helper(eq):
|
|
119
137
|
eq2 = _apart(eq)
|
|
120
138
|
if eq != eq2:
|
|
121
139
|
return eq2
|
|
140
|
+
|
|
122
141
|
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
123
142
|
return fx(helper(eq))
|
|
@@ -5,6 +5,7 @@ from .base import *
|
|
|
5
5
|
from .simplify import simplify,solve
|
|
6
6
|
from .expand import expand
|
|
7
7
|
import math
|
|
8
|
+
from .tool import poly
|
|
8
9
|
|
|
9
10
|
from collections import Counter
|
|
10
11
|
def multiset_intersection(*lists):
|
|
@@ -42,6 +43,7 @@ def take_common(eq):
|
|
|
42
43
|
eq2 = term_common(eq2)
|
|
43
44
|
if eq2.name == "f_mul":
|
|
44
45
|
return take_common(solve(summation([item2 for index, item2 in enumerate(eq.children) if index not in item]) + eq2))
|
|
46
|
+
break
|
|
45
47
|
return eq
|
|
46
48
|
return term_common(eq)
|
|
47
49
|
def take_common2(eq):
|
|
@@ -158,12 +160,6 @@ def rationalize_sqrt(eq):
|
|
|
158
160
|
return TreeNode(eq.name, [rationalize_sqrt(child) for child in eq.children])
|
|
159
161
|
def factorconst(eq):
|
|
160
162
|
return simplify(_factorconst(eq))
|
|
161
|
-
def factor_quad_formula_init():
|
|
162
|
-
var = ""
|
|
163
|
-
formula_list = [(f"(A*D^2+B*D+C)", f"A*(D-(-B+(B^2-4*A*C)^(1/2))/(2*A))*(D-(-B-(B^2-4*A*C)^(1/2))/(2*A))")]
|
|
164
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
165
|
-
expr = [[parse("A"), parse("1")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
166
|
-
return [formula_list, var, expr]
|
|
167
163
|
|
|
168
164
|
def factor_quar_formula_init():
|
|
169
165
|
var = ""
|
|
@@ -171,51 +167,115 @@ def factor_quar_formula_init():
|
|
|
171
167
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
172
168
|
expr = [[parse("A")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
173
169
|
return [formula_list, var, expr]
|
|
174
|
-
|
|
175
|
-
var = ""
|
|
176
|
-
formula_list = [(f"D^3+E", f"(D+E^(1/3))*(D^2-D*E^(1/3)+E^(2/3))"), (f"D^3-E", f"(D-E^(1/3))*(D^2+D*E^(1/3)+E^(2/3))"),\
|
|
177
|
-
(f"-D^3+E", f"(-D+E^(1/3))*(D^2+D*E^(1/3)+E^(2/3))")]
|
|
178
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
179
|
-
expr = [[parse("A")], [parse("B")]]
|
|
180
|
-
return [formula_list, var, expr]
|
|
181
|
-
formula_gen2 = factor_quad_formula_init()
|
|
182
|
-
formula_gen3 = factor_cube_formula_init()
|
|
170
|
+
|
|
183
171
|
formula_gen9 = factor_quar_formula_init()
|
|
184
172
|
def factor_helper(equation, complexnum, power=2):
|
|
185
|
-
global
|
|
186
|
-
|
|
173
|
+
global formula_gen9
|
|
174
|
+
|
|
175
|
+
maxnum=1
|
|
176
|
+
alloclst = []
|
|
177
|
+
for i in range(0,26):
|
|
178
|
+
if "v_"+str(i) not in vlist(equation):
|
|
179
|
+
alloclst.append("v_"+str(i))
|
|
180
|
+
r = alloclst.pop(0)
|
|
181
|
+
fx = None
|
|
182
|
+
curr = None
|
|
187
183
|
def high(eq):
|
|
188
184
|
nonlocal maxnum
|
|
189
185
|
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
190
186
|
n = int(eq.children[1].name[2:])
|
|
191
|
-
if n>power and n % power == 0:
|
|
192
|
-
|
|
187
|
+
if abs(n)>power and abs(n) % power == 0:
|
|
188
|
+
if abs(n)>abs(maxnum):
|
|
189
|
+
maxnum = n
|
|
193
190
|
for child in eq.children:
|
|
194
191
|
high(child)
|
|
195
192
|
def helper(eq):
|
|
196
|
-
nonlocal maxnum
|
|
197
|
-
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
193
|
+
nonlocal maxnum, fx, r
|
|
194
|
+
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_" and eq.children[0] == curr:
|
|
198
195
|
n = int(eq.children[1].name[2:])
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
out= (eq.children[0]**tree_form("d_"+str(sgn*int(n/power))))**power
|
|
196
|
+
if maxnum !=1 and n % maxnum == 0:
|
|
197
|
+
fx = lambda x: replace(x, tree_form(r), curr**tree_form("d_"+str(maxnum)))
|
|
198
|
+
out= tree_form(r)**tree_form("d_"+str(int(n/maxnum)))
|
|
203
199
|
return out
|
|
204
200
|
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
205
|
-
high(equation)
|
|
206
201
|
out = None
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
202
|
+
|
|
203
|
+
for i in range(2,4):
|
|
204
|
+
if power == i:
|
|
205
|
+
for curr in vlist(equation):
|
|
206
|
+
curr = tree_form(curr)
|
|
207
|
+
fx = None
|
|
208
|
+
maxnum = 1
|
|
209
|
+
high(equation.copy_tree())
|
|
210
|
+
|
|
211
|
+
if maxnum != 1:
|
|
212
|
+
maxnum= maxnum/power
|
|
213
|
+
maxnum = round(maxnum)
|
|
214
|
+
eq2 = helper(equation.copy_tree())
|
|
215
|
+
if not contain(eq2, tree_form(r)) or (contain(eq2, tree_form(r)) and not contain(eq2,curr)):
|
|
216
|
+
if not contain(eq2, tree_form(r)):
|
|
217
|
+
r = curr.name
|
|
218
|
+
fx = lambda x: x
|
|
219
|
+
|
|
220
|
+
lst = poly(eq2.copy_tree(), r)
|
|
221
|
+
if lst is not None and len(lst)==i+1:
|
|
222
|
+
|
|
223
|
+
success = True
|
|
224
|
+
if i == 2:
|
|
225
|
+
a, b, c = lst
|
|
226
|
+
x1 = (-b+(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
227
|
+
x2 = (-b-(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
228
|
+
x1 = simplify(x1)
|
|
229
|
+
x2 = simplify(x2)
|
|
230
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)
|
|
231
|
+
if not complexnum and (contain(x1, tree_form("s_i")) or contain(x2, tree_form("s_i"))):
|
|
232
|
+
success = False
|
|
233
|
+
else:
|
|
234
|
+
a, b, c, d = lst
|
|
235
|
+
B, C, D = b/a, c/a, d/a
|
|
236
|
+
p = C-(B**2)/3
|
|
237
|
+
q = 2*B**3/27-B*C/3+D
|
|
238
|
+
t = q**2/4+ p**3/27
|
|
239
|
+
u = (-q/2+t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
240
|
+
v = (-q/2-t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
241
|
+
y1 = u+v
|
|
242
|
+
three = 3**(tree_form("d_2")**-1)
|
|
243
|
+
y2 = -(u+v)/2+tree_form("s_i")*three*(u-v)/2
|
|
244
|
+
y3 = -(u+v)/2-tree_form("s_i")*three*(u-v)/2
|
|
245
|
+
x1,x2,x3 = y1-B/3 , y2-B/3, y3-B/3
|
|
246
|
+
x1,x2, x3 = simplify(x1), simplify(x2), simplify(x3)
|
|
247
|
+
out2 = None
|
|
248
|
+
if not complexnum:
|
|
249
|
+
for item in itertools.combinations([x1,x2,x3],2):
|
|
250
|
+
if all(contain(item2,tree_form("s_i")) for item2 in list(item)):
|
|
251
|
+
out2 = (tree_form(r)-item[0])*(tree_form(r)-item[1])
|
|
252
|
+
break
|
|
253
|
+
if out2 is not None:
|
|
254
|
+
out2 = simplify(expand(simplify(out2)))
|
|
255
|
+
out3 = None
|
|
256
|
+
for item in [x1, x2, x3]:
|
|
257
|
+
if not contain(item,tree_form("s_i")):
|
|
258
|
+
out3 = item
|
|
259
|
+
break
|
|
260
|
+
eq2 = a*(tree_form(r)-out3)*out2
|
|
261
|
+
|
|
262
|
+
else:
|
|
263
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)*(tree_form(r)-x3)
|
|
264
|
+
if success:
|
|
265
|
+
equation = fx(eq2)
|
|
266
|
+
break
|
|
267
|
+
|
|
268
|
+
if power == 4:
|
|
269
|
+
|
|
212
270
|
out = transform_formula(helper(equation), "v_0", formula_gen9[0], formula_gen9[1], formula_gen9[2])
|
|
271
|
+
|
|
213
272
|
if out is not None:
|
|
214
273
|
out = simplify(solve(out))
|
|
215
274
|
if out is not None and (complexnum or (not complexnum and not contain(out, tree_form("s_i")))):
|
|
216
275
|
return out
|
|
276
|
+
|
|
217
277
|
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
218
|
-
def factor(equation
|
|
219
|
-
return solve(take_common2(simplify(
|
|
278
|
+
def factor(equation):
|
|
279
|
+
return solve(take_common2(simplify(equation)))
|
|
220
280
|
def factor2(equation, complexnum=False):
|
|
221
281
|
return solve(factor_helper(solve(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3)), complexnum, 4))
|
|
@@ -31,8 +31,13 @@ def integrate_summation(equation):
|
|
|
31
31
|
def subs_heuristic(eq, var):
|
|
32
32
|
output = []
|
|
33
33
|
def collect2(eq):
|
|
34
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) == Fraction(1,2):
|
|
35
|
+
|
|
36
|
+
if eq.children[0] == var:
|
|
37
|
+
output.append(str_form(eq))
|
|
34
38
|
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator == 1 and abs(frac(eq.children[1]).numerator) % 2 == 0:
|
|
35
|
-
|
|
39
|
+
if len(eq.children[0].children) == 0 or eq.children[0].children[0] == var:
|
|
40
|
+
output.append(str_form(eq.children[0]**2))
|
|
36
41
|
if eq.name in ["f_pow", "f_sin", "f_cos", "f_arcsin"] and var.name in str_form(eq.children[0]):
|
|
37
42
|
if eq.children[0].name[:2] != "v_":
|
|
38
43
|
output.append(str_form(eq.children[0]))
|
|
@@ -57,7 +62,20 @@ def subs_heuristic(eq, var):
|
|
|
57
62
|
|
|
58
63
|
tmp = list(set([simplify(tree_form(x)) for x in output]))
|
|
59
64
|
tmp = sorted(tmp, key=lambda x: len(str(x)))
|
|
60
|
-
|
|
65
|
+
poly_term = None
|
|
66
|
+
term_degree = 100
|
|
67
|
+
output = []
|
|
68
|
+
for item in tmp:
|
|
69
|
+
n = poly(simplify(item), var.name)
|
|
70
|
+
if n is None:
|
|
71
|
+
output.append(item)
|
|
72
|
+
else:
|
|
73
|
+
if term_degree > len(n):
|
|
74
|
+
poly_term = item
|
|
75
|
+
term_degree = len(n)
|
|
76
|
+
if poly_term is None:
|
|
77
|
+
return tmp
|
|
78
|
+
return [poly_term]+output
|
|
61
79
|
try_index = []
|
|
62
80
|
try_lst = []
|
|
63
81
|
def ref(eq):
|
|
@@ -170,7 +188,7 @@ def integrate_subs(equation, term, v1, v2):
|
|
|
170
188
|
|
|
171
189
|
return none
|
|
172
190
|
|
|
173
|
-
return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(
|
|
191
|
+
return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(equation), tree_form(origv2)]),tree_form(origv2) ,g])
|
|
174
192
|
|
|
175
193
|
def integrate_subs_main(equation):
|
|
176
194
|
if equation.name == "f_ref":
|
|
@@ -359,10 +377,21 @@ def integration_formula_trig():
|
|
|
359
377
|
[parse("C"), parse("0"), parse("1")], [parse("D"), parse("0"), parse("1")],\
|
|
360
378
|
[parse("E"), parse("0"), parse("1")], [parse("F"), parse("0"), parse("1")]]
|
|
361
379
|
return [formula_list, var, expr]
|
|
362
|
-
|
|
363
|
-
|
|
364
380
|
formula_gen4 = integration_formula_trig()
|
|
365
381
|
|
|
382
|
+
def integration_formula_ex():
|
|
383
|
+
var = "x"
|
|
384
|
+
formula_list = [
|
|
385
|
+
(
|
|
386
|
+
f"e^(A*{var})*cos(B*{var})",
|
|
387
|
+
f"e^(A*{var})*(A*cos(B*{var}) + B*sin(B*{var}))/(A^2 + B^2)"
|
|
388
|
+
)
|
|
389
|
+
]
|
|
390
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
391
|
+
expr = [[parse("A"), parse("1")], [parse("B"), parse("1")]]
|
|
392
|
+
return [formula_list, var, expr]
|
|
393
|
+
|
|
394
|
+
formula_gen11 = integration_formula_ex()
|
|
366
395
|
def rm_const(equation):
|
|
367
396
|
if equation.name == "f_ref":
|
|
368
397
|
return equation
|
|
@@ -406,4 +435,9 @@ def integrate_formula(equation):
|
|
|
406
435
|
if out is not None:
|
|
407
436
|
|
|
408
437
|
return out
|
|
438
|
+
if "f_cos" in expr_str and contain(integrand, tree_form("s_e")):
|
|
439
|
+
out = transform_formula(integrand, wrt.name, formula_gen11[0], formula_gen11[1], formula_gen11[2])
|
|
440
|
+
if out is not None:
|
|
441
|
+
|
|
442
|
+
return out
|
|
409
443
|
return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
|
|
@@ -14,6 +14,7 @@ def substitute_val(eq, val, var="v_0"):
|
|
|
14
14
|
|
|
15
15
|
def subslimit(equation, var):
|
|
16
16
|
equation2 = trig0(replace(equation, var, tree_form("d_0")))
|
|
17
|
+
|
|
17
18
|
try:
|
|
18
19
|
tmp = simplify(equation2)
|
|
19
20
|
return simplify(expand(tmp))
|
|
@@ -35,6 +36,7 @@ def lhospital(num, den, steps,var):
|
|
|
35
36
|
logs = []
|
|
36
37
|
|
|
37
38
|
out = check(num, den, var)
|
|
39
|
+
|
|
38
40
|
if isinstance(out, TreeNode):
|
|
39
41
|
return out,[]
|
|
40
42
|
for _ in range(steps):
|
|
@@ -168,6 +168,15 @@ def clear_div(eq, denom=False):
|
|
|
168
168
|
return solve(product(lst2)),sign
|
|
169
169
|
|
|
170
170
|
def simplify(eq):
|
|
171
|
+
if "v_" not in str_form(eq):
|
|
172
|
+
n = frac(eq)
|
|
173
|
+
if n is not None:
|
|
174
|
+
if n.numerator == 0:
|
|
175
|
+
return tree_form("d_0")
|
|
176
|
+
if n.denominator != 1:
|
|
177
|
+
return tree_form("d_"+str(n.numerator))/tree_form("d_"+str(n.denominator))
|
|
178
|
+
else:
|
|
179
|
+
return tree_form("d_"+str(n.numerator))
|
|
171
180
|
error = False
|
|
172
181
|
eq = flatten_tree(eq)
|
|
173
182
|
if eq.name in ["f_and", "f_or", "f_not"]:
|
|
@@ -287,7 +296,9 @@ def simplify(eq):
|
|
|
287
296
|
error = True
|
|
288
297
|
else:
|
|
289
298
|
eq = tree_form("d_0")
|
|
290
|
-
|
|
299
|
+
if eq.name =="f_pow" and eq.children[0] == tree_form("s_i") and frac(eq.children[1])is not None and frac(eq.children[1]).denominator == 1:
|
|
300
|
+
n = frac(eq.children[1]).numerator
|
|
301
|
+
eq = {0:tree_form("d_1"), 1:tree_form("s_i"), 2:tree_form("d_-1"), 3:-tree_form("s_i")}[n%4]
|
|
291
302
|
if eq.name == "f_mul":
|
|
292
303
|
dic = {}
|
|
293
304
|
for child in eq.children:
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from .diff import diff
|
|
2
|
+
from .expand import expand
|
|
3
|
+
from .simplify import simplify, solve
|
|
4
|
+
from .base import *
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
def poly_div(dividend_coeffs, divisor_coeffs):
|
|
8
|
+
"""
|
|
9
|
+
Perform polynomial division using coefficients with symbolic simplification.
|
|
10
|
+
"""
|
|
11
|
+
# Deep copy inputs using copy_tree()
|
|
12
|
+
dividend = [item.copy_tree() for item in dividend_coeffs]
|
|
13
|
+
divisor = [item.copy_tree() for item in divisor_coeffs]
|
|
14
|
+
|
|
15
|
+
# Remove leading zeros
|
|
16
|
+
while len(dividend) > 1 and simplify(dividend[0]) == 0:
|
|
17
|
+
dividend.pop(0)
|
|
18
|
+
while len(divisor) > 1 and simplify(divisor[0]) == 0:
|
|
19
|
+
divisor.pop(0)
|
|
20
|
+
|
|
21
|
+
# Validate divisor
|
|
22
|
+
if len(divisor) == 0 or simplify(divisor[0]) == 0:
|
|
23
|
+
raise ValueError("Invalid divisor")
|
|
24
|
+
|
|
25
|
+
if len(dividend) < len(divisor):
|
|
26
|
+
return [tree_form("d_0")], [item.copy_tree() for item in dividend]
|
|
27
|
+
|
|
28
|
+
# Calculate degrees
|
|
29
|
+
deg_p = len(dividend) - 1
|
|
30
|
+
deg_q = len(divisor) - 1
|
|
31
|
+
deg_quot = deg_p - deg_q
|
|
32
|
+
|
|
33
|
+
# Initialize quotient (highest degree first)
|
|
34
|
+
quotient = [tree_form("d_0")] * (deg_quot + 1)
|
|
35
|
+
|
|
36
|
+
# Working dividend - keep original structure
|
|
37
|
+
working_dividend = [item.copy_tree() for item in dividend]
|
|
38
|
+
|
|
39
|
+
# Long division - align by current leading terms
|
|
40
|
+
for k in range(deg_quot, -1, -1):
|
|
41
|
+
# Remove leading zeros from working dividend
|
|
42
|
+
while len(working_dividend) > 1 and simplify(working_dividend[0]) == 0:
|
|
43
|
+
working_dividend.pop(0)
|
|
44
|
+
|
|
45
|
+
if len(working_dividend) == 0 or simplify(working_dividend[0]) == 0:
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
# Calculate quotient term for degree k
|
|
49
|
+
leading_ratio = simplify(working_dividend[0] / divisor[0])
|
|
50
|
+
quotient[k] = leading_ratio
|
|
51
|
+
|
|
52
|
+
# Subtract leading_ratio * divisor (aligned at leading terms)
|
|
53
|
+
new_dividend = []
|
|
54
|
+
for i in range(max(len(working_dividend), len(divisor))):
|
|
55
|
+
dividend_term = working_dividend[i] if i < len(working_dividend) else tree_form("d_0")
|
|
56
|
+
divisor_term = simplify(leading_ratio * divisor[i]) if i < len(divisor) else tree_form("d_0")
|
|
57
|
+
result = simplify(dividend_term - divisor_term)
|
|
58
|
+
new_dividend.append(result)
|
|
59
|
+
|
|
60
|
+
working_dividend = new_dividend
|
|
61
|
+
|
|
62
|
+
# Remainder is terms with degree < deg_q (last deg_q terms of final dividend)
|
|
63
|
+
remainder = working_dividend[-(deg_q):] if len(working_dividend) > deg_q else working_dividend
|
|
64
|
+
while len(remainder) > 1 and simplify(remainder[0]) == 0:
|
|
65
|
+
remainder.pop(0)
|
|
66
|
+
if not remainder:
|
|
67
|
+
remainder = [tree_form("d_0")]
|
|
68
|
+
|
|
69
|
+
# Clean quotient trailing zeros
|
|
70
|
+
while len(quotient) > 1 and simplify(quotient[-1]) == 0:
|
|
71
|
+
quotient.pop()
|
|
72
|
+
|
|
73
|
+
return quotient, remainder
|
|
74
|
+
|
|
75
|
+
def unpoly(eq, var):
|
|
76
|
+
eq = eq[::-1]
|
|
77
|
+
eq = [simplify(item) for item in eq]
|
|
78
|
+
eq2 = copy.deepcopy([eq[i]*tree_form(var)**tree_form("d_"+str(i)) if i != 0 else eq[i] for i in range(len(eq))])
|
|
79
|
+
return summation(eq2)
|
|
80
|
+
|
|
81
|
+
def longdiv(p, q, p_min=0, q_min=0):
|
|
82
|
+
p, q = simplify(p), simplify(q)
|
|
83
|
+
|
|
84
|
+
var = set(vlist(p)) & set(vlist(q))
|
|
85
|
+
if len(var) > 0:
|
|
86
|
+
var = list(var)[0]
|
|
87
|
+
p = poly(p, var)
|
|
88
|
+
q = poly(q, var)
|
|
89
|
+
if p is not None and q is not None and len(p)-1>=p_min and len(q)-1>=q_min and len(p)<=len(q):
|
|
90
|
+
a, b = poly_div(p, q)
|
|
91
|
+
return unpoly(a, var), unpoly(b, var)
|
|
92
|
+
return None
|
|
93
|
+
def poly_simplify(eq):
|
|
94
|
+
a, b = num_dem(eq)
|
|
95
|
+
b = simplify(b)
|
|
96
|
+
if b != 1:
|
|
97
|
+
return simplify(poly_simplify(a)/poly_simplify(b))
|
|
98
|
+
for var in vlist(eq):
|
|
99
|
+
n = poly(eq, var, 20)
|
|
100
|
+
if n is not None:
|
|
101
|
+
return simplify(unpoly(n, var))
|
|
102
|
+
return TreeNode(eq.name, [poly_simplify(child) for child in eq.children])
|
|
103
|
+
def enclose_const(eq):
|
|
104
|
+
def req(eq, dic):
|
|
105
|
+
for key in dic.keys():
|
|
106
|
+
eq = replace(eq, dic[key], key)
|
|
107
|
+
return eq
|
|
108
|
+
alloclst = []
|
|
109
|
+
for i in range(0,26):
|
|
110
|
+
if "v_"+str(i) not in vlist(eq):
|
|
111
|
+
alloclst.append(tree_form("v_"+str(i)))
|
|
112
|
+
dic = {}
|
|
113
|
+
def helper(eq):
|
|
114
|
+
nonlocal alloclst, dic
|
|
115
|
+
if frac(eq) is not None:
|
|
116
|
+
return eq
|
|
117
|
+
|
|
118
|
+
if "v_" not in str_form(eq):
|
|
119
|
+
if eq not in dic.keys():
|
|
120
|
+
n = alloclst.pop(0)
|
|
121
|
+
dic[eq] = n
|
|
122
|
+
return dic[eq]
|
|
123
|
+
else:
|
|
124
|
+
if eq.name == "f_pow":
|
|
125
|
+
return TreeNode(eq.name, [helper(eq.children[0]), eq.children[1]])
|
|
126
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
127
|
+
eq= helper(eq)
|
|
128
|
+
return eq, lambda x: req(x, dic)
|
|
129
|
+
|
|
130
|
+
def poly(eq, to_compute, m=10):
|
|
131
|
+
def substitute_val(eq, val, var="v_0"):
|
|
132
|
+
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
|
133
|
+
return eq
|
|
134
|
+
def inv(eq):
|
|
135
|
+
if eq.name[:2] == "f_" and eq.name[2:] in "ref try integrate subs".split(" "):
|
|
136
|
+
return False
|
|
137
|
+
if eq.name[2:] in ["sin", "cos", "log"] and contain(eq.children[0], tree_form(to_compute)):
|
|
138
|
+
return False
|
|
139
|
+
if eq.name == "f_pow" and contain(eq.children[0], tree_form(to_compute)) and\
|
|
140
|
+
(frac(eq.children[1]) is None or frac(eq.children[1]) < 0 or frac(eq.children[1]).denominator != 1):
|
|
141
|
+
return False
|
|
142
|
+
if eq.name == "f_abs":
|
|
143
|
+
return False
|
|
144
|
+
if any(not inv(child) for child in eq.children):
|
|
145
|
+
return False
|
|
146
|
+
return True
|
|
147
|
+
if not inv(eq):
|
|
148
|
+
return None
|
|
149
|
+
out = []
|
|
150
|
+
eq2 = eq
|
|
151
|
+
for i in range(m):
|
|
152
|
+
out.append(expand(simplify(eq2)))
|
|
153
|
+
eq2 = diff(eq2, to_compute)
|
|
154
|
+
for i in range(len(out)-1,-1,-1):
|
|
155
|
+
if out[i] == tree_form("d_0"):
|
|
156
|
+
out.pop(i)
|
|
157
|
+
else:
|
|
158
|
+
break
|
|
159
|
+
final = []
|
|
160
|
+
for index, item in enumerate(out):
|
|
161
|
+
final.append(substitute_val(item, 0, to_compute)/tree_form("d_"+str(math.factorial(index))))
|
|
162
|
+
|
|
163
|
+
return [expand(simplify(item)) for item in final][::-1]
|
|
@@ -58,6 +58,9 @@ def trig0(eq):
|
|
|
58
58
|
if a > b:
|
|
59
59
|
a = 2*b - a
|
|
60
60
|
return a, b
|
|
61
|
+
if eq.name == "f_arccosec":
|
|
62
|
+
return (1/eq.children[0]).fx("arcsin")
|
|
63
|
+
|
|
61
64
|
if eq.name == "f_arctan":
|
|
62
65
|
if eq.children[0].name == "d_0":
|
|
63
66
|
return tree_form("d_0")
|
|
@@ -164,52 +167,61 @@ def _trig1(equation):
|
|
|
164
167
|
return TreeNode(equation.name, [_trig1(child) for child in equation.children])
|
|
165
168
|
def trig1(eq):
|
|
166
169
|
return simplify(_trig1(noneg_pow(eq)))
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if len(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
170
|
+
def trig4(eq):
|
|
171
|
+
done = False
|
|
172
|
+
def _trig4(eq, numer=True, chance="sin"):
|
|
173
|
+
nonlocal done
|
|
174
|
+
if eq.name == "f_sin":
|
|
175
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
176
|
+
r = len(eq.children[0].children)%2
|
|
177
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
178
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
179
|
+
if len(a.children)==1:
|
|
180
|
+
a=a.children[0]
|
|
181
|
+
if len(b.children)==1:
|
|
182
|
+
b=b.children[0]
|
|
183
|
+
return a.fx("sin")*b.fx("cos") + a.fx("cos")*b.fx("sin")
|
|
184
|
+
if eq.children[0].name == "f_arccos":
|
|
185
|
+
a = eq.children[0].children[0]
|
|
186
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
|
187
|
+
if eq.children[0].name == "f_arctan":
|
|
188
|
+
a = eq.children[0].children[0]
|
|
189
|
+
return a/(1+a**2)**(tree_form("d_2")**-1)
|
|
190
|
+
if eq.name == "f_pow" and numer:
|
|
191
|
+
if eq.children[0].name == "f_cos" and chance == "cos":
|
|
192
|
+
a = eq.children[0].children[0]
|
|
193
|
+
if frac(eq.children[1]) == 2:
|
|
194
|
+
done = True
|
|
195
|
+
return 1 - a.fx("sin")**2
|
|
196
|
+
if eq.children[0].name == "f_sin" and chance == "cos":
|
|
197
|
+
a = eq.children[0].children[0]
|
|
198
|
+
if frac(eq.children[1]) == 2:
|
|
199
|
+
done = True
|
|
200
|
+
return 1 - a.fx("cos")**2
|
|
201
|
+
if eq.name == "f_cos":
|
|
202
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
203
|
+
r = len(eq.children[0].children)%2
|
|
204
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
205
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
206
|
+
if len(a.children)==1:
|
|
207
|
+
a=a.children[0]
|
|
208
|
+
if len(b.children)==1:
|
|
209
|
+
b=b.children[0]
|
|
210
|
+
return a.fx("cos")*b.fx("cos") - a.fx("sin")*b.fx("sin")
|
|
211
|
+
if eq.children[0].name == "f_arcsin":
|
|
212
|
+
a = eq.children[0].children[0]
|
|
213
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
|
214
|
+
if eq.children[0].name == "f_arctan":
|
|
215
|
+
a = eq.children[0].children[0]
|
|
216
|
+
return tree_form("d_1")/(1+a**2)**(tree_form("d_2")**-1)
|
|
217
|
+
|
|
218
|
+
return TreeNode(eq.name, [_trig4(child, False, chance) if eq.name != "f_add" and\
|
|
219
|
+
(not numer or (eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) < 0))\
|
|
220
|
+
else _trig4(child, True, chance) for child in eq.children])
|
|
221
|
+
eq= _trig4(eq)
|
|
222
|
+
if not done:
|
|
223
|
+
eq = _trig4(eq,"cos")
|
|
224
|
+
return eq
|
|
213
225
|
def trig2(eq):
|
|
214
226
|
# Base case: if not an addition, recurse into children
|
|
215
227
|
if eq.name != "f_add":
|
|
@@ -245,4 +257,3 @@ def trig2(eq):
|
|
|
245
257
|
|
|
246
258
|
# If no sin/cos pairs found, just recurse on children
|
|
247
259
|
return TreeNode(eq.name, [trig2(child) for child in eq.children])
|
|
248
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathai
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.8
|
|
4
4
|
Summary: Mathematics solving Ai tailored to NCERT
|
|
5
5
|
Home-page: https://github.com/infinity390/mathai4
|
|
6
6
|
Author: educated indians are having a low iq and are good for nothing
|
|
@@ -16,6 +16,9 @@ Dynamic: requires-python
|
|
|
16
16
|
Dynamic: summary
|
|
17
17
|
|
|
18
18
|
# Math AI Documentation
|
|
19
|
+
## Source
|
|
20
|
+
Github repository of the code
|
|
21
|
+
https://github.com/infinity390/mathai4
|
|
19
22
|
|
|
20
23
|
## Philosophy
|
|
21
24
|
I think it is a big realization in computer science and programming to realize that computers can solve mathematics.
|
mathai-0.4.6/mathai/tool.py
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
from .diff import diff
|
|
2
|
-
from .expand import expand
|
|
3
|
-
from .simplify import simplify
|
|
4
|
-
from .base import *
|
|
5
|
-
import math
|
|
6
|
-
|
|
7
|
-
def enclose_const(eq):
|
|
8
|
-
def req(eq, dic):
|
|
9
|
-
for key in dic.keys():
|
|
10
|
-
eq = replace(eq, dic[key], key)
|
|
11
|
-
return eq
|
|
12
|
-
alloclst = []
|
|
13
|
-
for i in range(0,26):
|
|
14
|
-
if "v_"+str(i) not in vlist(eq):
|
|
15
|
-
alloclst.append(tree_form("v_"+str(i)))
|
|
16
|
-
dic = {}
|
|
17
|
-
def helper(eq):
|
|
18
|
-
nonlocal alloclst, dic
|
|
19
|
-
if frac(eq) is not None:
|
|
20
|
-
return eq
|
|
21
|
-
|
|
22
|
-
if "v_" not in str_form(eq):
|
|
23
|
-
if eq not in dic.keys():
|
|
24
|
-
n = alloclst.pop(0)
|
|
25
|
-
dic[eq] = n
|
|
26
|
-
return dic[eq]
|
|
27
|
-
else:
|
|
28
|
-
if eq.name == "f_pow":
|
|
29
|
-
return TreeNode(eq.name, [helper(eq.children[0]), eq.children[1]])
|
|
30
|
-
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
31
|
-
eq= helper(eq)
|
|
32
|
-
return eq, lambda x: req(x, dic)
|
|
33
|
-
|
|
34
|
-
def poly(eq, to_compute):
|
|
35
|
-
def substitute_val(eq, val, var="v_0"):
|
|
36
|
-
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
|
37
|
-
return eq
|
|
38
|
-
def inv(eq):
|
|
39
|
-
if eq.name == "f_pow" and "v_" in str_form(eq.children[0]) and eq.children[1] == tree_form("d_-1"):
|
|
40
|
-
return False
|
|
41
|
-
if eq.name == "f_abs":
|
|
42
|
-
return False
|
|
43
|
-
if any(not inv(child) for child in eq.children):
|
|
44
|
-
return False
|
|
45
|
-
return True
|
|
46
|
-
if not inv(eq):
|
|
47
|
-
return None
|
|
48
|
-
out = []
|
|
49
|
-
eq2 = eq
|
|
50
|
-
for i in range(10):
|
|
51
|
-
out.append(expand(simplify(eq2)))
|
|
52
|
-
eq2 = diff(eq2, to_compute)
|
|
53
|
-
for i in range(len(out)-1,-1,-1):
|
|
54
|
-
if out[i] == tree_form("d_0"):
|
|
55
|
-
out.pop(i)
|
|
56
|
-
else:
|
|
57
|
-
break
|
|
58
|
-
final = []
|
|
59
|
-
for index, item in enumerate(out):
|
|
60
|
-
final.append(substitute_val(item, 0, to_compute)/tree_form("d_"+str(math.factorial(index))))
|
|
61
|
-
|
|
62
|
-
return [expand(simplify(item)) for item in final][::-1]
|
|
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
|